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).reprjest 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żywareprdo wyświetlenia wartości zmiennej. Stwórzmy słownikdz 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).lenjest 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żyjemydeldla 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]