Zanurkuj w Pythonie/Zaawansowane metody specjalne
Zaawansowane metody specjalne
[edytuj]W Pythonie, oprócz __getitem__ i __setitem__, są jeszcze inne metody specjalne, . Niektóre z nich pozwalają dodać funkcjonalność, której się nawet nie spodziewamy. Ten przykład pokazuje inne metody specjalne znanej już nam klasy UserDict
.
UserDict
def __repr__(self): return repr(self.data) #(1)
def __cmp__(self, dict): #(2)
if isinstance(dict, UserDict):
return cmp(self.data, dict.data)
else:
return cmp(self.data, dict)
def __len__(self): return len(self.data) #(3)
def __delitem__(self, key): del self.data[key] #(4)
__repr__
jest metodą specjalną, która zostanie wywołana, gdy użyjemyrepr(obiekt)
.repr
jest wbudowaną funkcją Pythona, która zwraca reprezentację danego obiektu w postaci łańcucha znaków. Działa dla dowolnych obiektów, nie tylko obiektów klas. Już wielokrotnie używaliśmy tej funkcji, nawet o tym nie wiedząc. Gdy w oknie interaktywnym wpisujemy nazwę zmiennej i naciskamy ENTER, Python używarepr
do wyświetlenia wartości zmiennej. Stwórzmy słownikd
z jakimiś danymi i wywołajmyrepr(d)
, żeby się o tym przekonać.- Metoda
__cmp__
zostanie wywoływana, gdy porównujemy za pomocą==
dwa dowolne obiekty Pythona, nie tylko instancje klas. Aby porównać wbudowane typy danych (i nie tylko), wykorzystywane są pewne reguły np. słowniki są sobie równe, gdy mają dokładnie takie same pary klucz-wartość; łańcuchy znaków są sobie równe, gdy mają taką samą długość i zawierają taki sam ciąg znaków. Dla instancji klas możemy zdefiniować metodę__cmp__
i zaimplementować sposób porównania własnoręcznie, a potem używać==
do porównywania obiektów klasy. Python wywoła__cmp__
za nas. - Metoda
__len__
zostanie wywołana, gdy użyjemylen(obiekt)
.len
jest wbudowaną funkcją Pythona, która zwraca długość obiektu. Ta metoda działa dla dowolnego obiektu, który można uznać za obiekt posiadający jakąś długość. Długość łańcucha znaków jest równa ilości jego znaków, długość słownika, to liczba jego kluczy, a długość listy lub krotki to liczba ich elementów. Dla obiektów klas możesz zdefiniować metodę__len__
i samemu zaimplementować obliczanie długości, a następnie możemy używaćlen(obiekt)
. Python za nas wywoła metodę specjalną__len__
. - Metoda
__delitem__
zostanie wywołana, gdy użyjemydel obiekt[klucz]
. Dzięki tej funkcji możemy usuwać pojedyncze elementy ze słownika. Kiedy użyjemydel
dla pewnej instancji, Python wywoła metodę__delitem__
za nas.
W Javie sprawdzamy, czy dwie referencje do łańcucha znaków zajmują to samo fizyczne miejsce w pamięci, używając str1 == str2 . Jest to zwane identycznością obiektów i w Pythonie zapisywane jest jako str1 is str2 . Aby porównać wartości łańcuchów znaków w Javie, użylibyśmy str1.equals(str2) . W Pythonie uzyskujemy to samo, gdy napiszemy str1 == str2 . Programiści Javy, którzy zostali nauczeni, że świat jest lepszy, ponieważ == w Javie porównuje identyczność, zamiast wartości, mogą mieć trudności z akceptacją braku tego "dobra" w Pythonie.
|
Metody specjalne sprawiają, że dowolna klasa może przechowywać pary klucz-wartość w ten sposób, jak to robi słownik. W tym celu definiujemy metodę __setitem__
. Każda klasa może działać jak sekwencja, dzięki metodzie __getitem__
. Obiekty dowolnej klasy, które posiadają metodę __cmp__
, mogą być porównywane przy użyciu ==
. A jeśli dana klasa reprezentuje coś, co ma pewną długość, nie musimy definiować metody getLength
; po prostu definiujemy metodę __len__
i korzystamy z len(obiekt)
.
Inne obiektowo zorientowane języki programowania pozwalają nam zdefiniować tylko fizyczny model obiektu ("Ten obiekt ma metodę getLength "). Metody specjalne Pythona pozwalają zdefiniować logiczny model obiektu ("ten obiekt ma długość").
|
Python posiada wiele innych metod specjalnych. Są takie, które pozwalają klasie zachowywać się jak liczby, umożliwiając dodawanie, odejmowanie i inne operacje arytmetyczne na obiektach. (Klasycznym przykładem jest klasa reprezentująca liczby zespolone z częścią rzeczywistą i urojoną, na których możemy wykonywać wszystkie działania). Metoda __call__
pozwala klasie zachowywać się jak funkcja, a dzięki czemu możemy bezpośrednio wywoływać instancję pewnej klasy.
Materiały dodatkowe
[edytuj]