Rozdział 14 · Tworzenie rzeczywistych obiektów

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 piszeszCo 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:

str_metod.py
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:

eq_metod.py
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
Debug Lab 12: __eq__ został zidentyfikowany, a obiekt stał się unhashable
unhashable_obekt.py
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'
Co widać na ekranie

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.

Poprawiony kod
s_hash.py
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

    def __hash__(self):
        return hash((self.x, self.y))
Praktyka: Metody specjalne
interaktywny laptop bezpośrednio w przeglądarce – Python 3.14 przez Pyodide, bez instalacji
Otwórz praktykę →