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?
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.