Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

De onde vem o Other?

No sentido literal eu compreendo que other signifique outro, se referindo a o outro objeto que vamos comparar, mas porque other? De onde ele vem? Eu poderia usar qualquer coisa? O parametro pode receber qualquer objeto como parametro?

1 resposta
solução!

Oi @Bruno

1. "De onde vem o Other?"

O método especial __eq__ é chamado quando se utiliza o operador de comparação (==).

A expressão a == b é interpretada como a.__eq__(b). Neste caso, o objeto a será passado como o parâmetro self, e b como other.

Caso a classe de a não tenha implementado um método __eq__, o interpretador tentará chamar b.__eq__(a). Neste caso, o objeto a será passado como o parâmetro other, e b como self.

2. "mas por que other? Eu poderia usar qualquer coisa?"

O nome other é apenas uma convenção. Ao definir a sua própria classe você pode escolher outro nome. Algumas pessoas utilizam o nome value:

class Foo:
    def __eq__(self, value):
        # code

3. "O parâmetro pode receber qualquer objeto como parâmetro?"

Sim. Absolutamente qualquer coisa.

Por isso você deve tomar cuidado na implementação para evitar uma exceção AttributeError.

Exemplo:

Considere a classe Foo abaixo, e os objetos foo e bar.

class Foo:
    def __init__(self, a: int, b: int):
        self.a = a
        self.b = b

    def __eq__(self, other):
        print("Operador __eq__ da classe Foo")
        return self.a == other.a and self.b == other.b

foo = Foo(1, 2)
bar = Foo(1, 2)

Podemos comparar a igualdade entre eles:

>>> print(foo == bar)  # foo.__eq__(bar)
Operador __eq__ da classe Foo
True

Porém, o usuário poderia comparar com um objeto de outra classe que não tenha atributos a e b, recebendo AttributeError:

>>> print(foo == (1, 2))  # foo.__eq__((1, 2))
Traceback (most recent call last):
AttributeError: 'tuple' object has no attribute 'a'

Para resolver isso, precisamos reescrever o método __eq__:

def __eq__(self, other):
    print("Operador __eq__ da classe Foo")
    try:
        return self.a == other.a and self.b == other.b
    except AttributeError:
        return False

Exemplo 2:

Considere uma nova classe chamada NotFoo, que não tem método __eq__:

class NotFoo:
    def __init__(self, a: int, b: int):
        self.a = a
        self.b = b

notfoo = NotFoo(1, 2)

Ainda podemos comparar a igualdade dela com a classe Foo:

>>> print(notfoo == foo)  # notfoo.__eq__(foo)?
Operador __eq__ da classe Foo
True

Note que o interpretador Python percebeu que a classe NotFoo não tem um método __eq__ e, por isso, chamou o método __eq__ da classe Foo. Ou seja: como não é possível chamar notfoo.__eq__(foo), ele chama foo.__eq__(notfoo).

Exemplo 3:

Vamos testar o que acontece caso você implemente um método __eq__ na classe NotFoo:

class NotFoo:
    def __init__(self, a: int, b: int):
        self.a = a
        self.b = b

    def __eq__(self, other):
        print("Operador __eq__ da classe NotFoo")
        return self.a == other.a and self.b == other.b

Vamos rodar o mesmo código do exemplo 2:

>>> print(notfoo == foo)  # notfoo.__eq__(foo)
Operador __eq__ da classe NotFoo
True

Dessa vez, foi chamado o método __eq__ da classe NotFoo.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software