Zanurkuj w Pythonie/Metody specjalne: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 4:
Oprócz normalnych metod, jest też kilka metod specjalnych, które można definiować w klasach Pythona. Nie są one wywoływane bezpośrednio z Twojego kodu (jak zwykłe metody). Wywołuje je za Ciebie Python w określonych okolicznościach lub gdy użyjesz określonej składni.
Jak zauważyłeś w poprzednim rozdziale, użycie normalnych metod pozwala zrobić duży krok w stronę obudowania słownika klasą. Ale ponieważ możesz zrobić ze słownikiem dużo więcej, niż wywołać jego metody, normalne metody nie wystarczają. Możesz na przykład pobierać i dodawać elementy, używając składni nie wywołując metod jawnie. W tym przypadku przydadzą się
'''Przykład 5.12 Metoda <tt>__getitem__</tt>'''
Linia 18:
'/music/_singles/kairo.mp3'
# Metoda specjalna <tt>__getitem__</tt> wygląda dość prosto. Tak jak zwykłe metody <tt>clear</tt> <tt>keys</tt> i <tt>values</tt> po prostu pozwala słownikowi zwrócić
#Takiej składni użyłbyś, by dostać wartość ze słownika i dokładnie tę wartość dostajesz. A brakujące ogniwo jest takie: wewnętrznie Python przekształcił tę składnię na wywołanie metody <tt>f.__getitem__("name")</tt>. Właśnie dlatego <tt>__getitem__</tt> jest specjalną metodą: nie tylko możesz ją zawołać ale Python woła ją za Ciebie, gdy użyjesz odpowiedniej składni.
Linia 41:
<tt>__setitem__</tt> jest metodą specjalną, ponieważ Python wywołuje ją za Ciebie, ale ciągle jest metodą klasy. Tak łatwo, jak zdefiniowałeś ją w klasie <tt>UserDict</tt>, możesz ją przedefiniować w klasach pochodnych i zasłonić metodę klasy podstawowej. To pozwala Ci definiować klasy, które czasami zachowują się jak zwykły słownik ale potrafią coś więcej.
Koncepcja ta jest
Na przykład <tt>MP3FileInfo</tt> jest potomkiem <tt>FileInfo</tt>. Kiedy w <tt>MP3FileInfo</tt> ustawiamy klucz <tt>"name"</tt>, nie tylko ustawiamy sam klucz <tt>"name"</tt> (jak to robi jego przodek <tt>FileInfo</tt>), lecz także
'''Przykład 5.14. Nadpisywanie metody <tt>__setitem__</tt> w klasie <tt>MP3FileInfo</tt>'''
Linia 52:
# Zauważmy, że <tt>__setitem__</tt> jest definiowany w identyczny sposób, jak w klasie przodka. Jest to ważne, ponieważ Python będzie wywoływał tę metodą oczekując odpowiedniej liczby argumentów.(Ściśle mówiąc, nazwy argumentów nic nie znaczą, ważna jest ich ilość.)
# W tym miejscu jest
# Dodatkowe operacje dla klucza <tt>"name"</tt> zawarte są w metodzie <tt>__parse</tt>. Jest to inna metoda klasy <tt>MP3FileInfo</tt> i kiedy ją wywołujemy, używamy przy tym zmiennej <tt>self</tt>. Wywołując samo <tt>__parse</tt> odnosimy się do normalnej funkcji, która jest zdefiniowana poza klasą, a tego nie chcemy wykonać. Kiedy natomiast wywołamy <tt>self.__parse</tt> będziemy odnosić się do metody znajdującej się wewnątrz klasy. Nie jest to niczym nowym. W identyczny sposób odnosimy się do atrybutów klasy.
# Po wykonaniu tej dodatkowej operacji, chcemy wykonać metodę przodka.
{{Infobox|
Linia 77:
'comment': 'http://mp3.com/cynicproject'}
# Najpierw tworzysz instancję klasy <tt>MP3FileInfo</tt>
# Teraz rozpoczyna się prawdziwa zabawa. Ustawiając klucz <tt>"name"</tt> w <tt>mp3file</tt> powoduje wywołanie metody <tt>__setitem__</tt> klasy <tt>MP3FileInfo</tt> (nie <tt>UserDict</tt>), która zauważa, że ustawiamy klucz <tt>"name"</tt> z prawdziwą wartością i wywołuje <tt>self.__parse</tt>. Chociaż jeszcze nie śledziliśmy działania metody <tt>__parse</tt>, możemy po wyjściu zobaczyć, że ustawia ona kilka innych kluczy jak <tt>"album"</tt>, <tt>"artist"</tt>, <tt>"genre"</tt>, <tt>"title"</tt>, <tt>"year"</tt>, czy też <tt>"comment"</tt>.
# Zmieniając klucz <tt>"name"</tt> będziemy wykonywali ten sam proces podobnie. Python wywoła <tt>__setitem__</tt>, który następnie wywoła <tt>self.__parse</tt>, a ten ustawi wszystkie inne klucze.
|