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?
Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!
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?
Oi @Bruno
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.
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):
# codeSim. Absolutamente qualquer coisa.
Por isso você deve tomar cuidado na implementação para evitar uma exceção AttributeError.
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
TruePoré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 FalseConsidere 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
TrueNote 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).
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.bVamos rodar o mesmo código do exemplo 2:
>>> print(notfoo == foo) # notfoo.__eq__(foo)
Operador __eq__ da classe NotFoo
TrueDessa vez, foi chamado o método __eq__ da classe NotFoo.