Metody specjalne
__init__ nie jest jedyną metodą Dundera. __str__ i __eq__ łączą obiekt z print() i ==.
Jak obiekty łączą się z wbudowanymi operacjami
Kiedy piszesz print(rex) lub len(text)
Python faktycznie wywołuje specjalną metodę na obiekcie o nazwie widoku
__имя__ („dander”, double underscore). Już korzystaliście
z takiej metody od początku rozdziału — __init__.
| To, co piszesz | Co Python wywołuje w rzeczywistości |
|---|---|
Sobaka("Рекс", 3) | __init__(self, ...) |
print(rex) | __str__(self) |
len(korzina) | __len__(self) |
a + b | __add__(self, other) |
a == b | __eq__(self, other) |
__str__ i __repr__
Bez specjalnej metody print(объект) usuwa bezużyteczność
linijka jak <__main__.Sobaka object at 0x7f...>.
__str__ pozwala ustawić czytelny dla człowieka wygląd:
class Sobaka:
def __init__(self, klichka, vozrast):
self.klichka = klichka
self.vozrast = vozrast
def __str__(self):
return f"{self.klichka} ({self.vozrast} roku)"
rex = Sobaka(„Rex”, 3)
print(rex) # Rex (3 lata) – nie jest adresem pamięci
__eq__: porównania przez znaczenie, a nie przez tożsamość
W rozdziale 14.9 a1 == a2 dwa Player z tym samym
wartości okazały się False bo ==
domyślnie porównuje obiekty jako różne lokalizacje pamięci.
__eq__ to zmienia:
class Sobaka:
def __init__(self, klichka, vozrast):
self.klichka = klichka
self.vozrast = vozrast
def __eq__(self, other):
return self.klichka == other.klichka and self.vozrast == other.vozrast
Sobaka(„Rex”, 3) == Sobaka(„Rex”, 3) # teraz True
class Tochka:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
tochki = {Tochka(1, 2), Tochka(3, 4)} # umieść przedmioty w zbiór
Traceback (most recent call last):
TypeError: unhashable type: 'Tochka'
Obiekt ma automatyczną __hash__, oparty na jego adresie w pamięci. Jak tylko określisz swój __eq__, Python USUWA AUTOMATYCZNIE __hash__ — ponieważ jeśli obiekty są „równe” pod względem wartości, logiczne jest, że mają też taki sam hash, a stary adresowy hash już temu nie odpowiada. Obiektu bez hasha nie można umieścić w set lub użyć jako klucz dict.
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __hash__(self):
return hash((self.x, self.y))