Zanurkuj w Pythonie/Metody specjalne: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Piotr (dyskusja | edycje)
mNie podano opisu zmian
Piotr (dyskusja | edycje)
mNie podano opisu zmian
Linia 17:
 
# Metoda specjalna <code>__getitem__</code> wygląda dość prosto. Ta metoda specjalna pozwala słownikowi zwrócić pewną wartość na podstawie podanego klucza. A jak ta metodę możemy wywołać? Możemy to zrobić bezpośrednio, ale w praktyce nie robimy w ten sposób, byłoby to niezbyt wygodne. Najlepiej pozwolić Pythonowi wywołać tę metodę za nas.
# Z takiej składni korzystamy, by dostać pewną wartość ze słownika. W rzeczywistości Python automatycznie przekształca taką składnię na wywołanie metody <code>f.__getitem__("plik")</code>. Właśnie dlatego <code>__getitem__</code> nazywamy metodą specjalną: nie tylko możemy ją zawołaćwywołać, ale Python wywołuje tę metodę także za nas, kiedy skorzystamy z odpowiedniej składni.
}}
 
Linia 54:
# Zwróćmy uwagę na kolejność i liczbę argumentów w <code>__setitem__</code>. Pierwszym argumentem jest instancja danej klasy (argument <code>self</code>), z której ta metoda została wywołana, następnym argumentem jest klucz (argument <code>key</code>), który chcemy ustawić, a trzecim jest wartość (argument <code>item</code>), którą chcemy skojarzyć z danym kluczem. Kolejność ta jest ważna, ponieważ Python będzie wywoływał tę metodą w takiej kolejności i z taką liczbą argumentów. (Nazwy argumentów nic nie znaczą, ważna jest ich ilość i kolejność.)
# W tym miejscu zawarte jest sedno całej klasy <tt>MP3FileInfo</tt>: jeśli przypisujemy pewną wartość do klucza <tt>"plik"</tt>, chcemy wykonać dodatkowo pewne operacje.
# Dodatkowe operacje dla klucza <tt>"plik"</tt> zawarte są w metodzie <code>__parse</code>. Jest to inna metoda klasy <code>MP3FileInfo</code>. Kiedy wywołujemy metodę <code>__parse</code> używamy zmiennej <code>self</code>. Gdybyśmy wywołali samo <code>__parse</code>, odnieślibyśmy się do normalnej funkcji, która jest zdefiniowana poza klasą, a tego nie chcemy wykonać. Kiedy natomiast wywołamy <code>self.__parse</code> będziemy odnosić się do metody znajdującej się wewnątrz klasy. Nie jest to niczym nowym. W identyczny sposób odnosimy się do [[../Klasa opakowująca UserDict|atrybutów klasyobiektu]].
# Po wykonaniu tej dodatkowej operacji, chcemy wykonać metodę nadklasy. Pamiętajmy, że Python nigdy nie zrobi to za nas; musimy zrobić to ręcznie. Zwróćmy uwagę na to, że odwołujemy się do bezpośredniej nadklasy, czyli do <code>FileInfo</code>, chociaż on nie posiada żadnej metody o nazwie <code>__setitem__</code>. Jednak wszystko jest w porządku, ponieważ Python będzie wędrował po drzewie przodków jeszcze wyżej dopóki nie znajdzie klasy, która posiada metodę, którą wywołujemy. Tak więc ta linia kodu znajdzie i wywoła metodę <code>__setitem__</code>, która jest zdefiniowana w samej wbudowanej klasie słownika, w klasie <code>dict</code>.
 
{{Infobox|
Kiedy odwołujemy się do danych zawartych w atrybucie klasyinstancji, musimy określić nazwę atrybutu np. <code>self.attribute</code>. Podczas wywoływania metody klasy, musiszmusimy określić nazwę metody np. <code>self.method</code>.
}}
 
Linia 79:
'artysta': 'The Cynic Project', 'gatunek': 18}</nowiki>}}
 
# Najpierw tworzymy instancję klasy <code>MP3FileInfo</code> bez podawania nazwy pliku. (Możemy tak zrobić, ponieważ argument <code>filename</code> metody <code>__init__</code> jest opcjonalny.) Ponieważ <code>MP3FileInfo</code> nie posiada własnej metody <code>__init__</code>, Python idzie wyżej po drzewie nadklas i znajduje metodę <code>__init__</code> w klasie <code>FileInfo</code>. Z kolei <code>__init__</code> w tej klasie ręcznie wykonuje metodę <code>__init__</code> w klasie <code>dict</code>, a potem ustawia klucz <code>"plik"</code> na wartość w zmiennej <code>filename</code>, który wynosi <code>None</code>, ponieważ pominęliśmy nazwę pliku. Ostatecznie <code>mp3file</code> początkowo jest słownikiem (właściwie podklasąklasą potomną słownika) z jednym kluczem <code>"plik"</code>, którego wartość wynosi <ttcode>None</ttcode>.
# Teraz rozpoczyna się prawdziwa zabawa. Ustawiając klucz <code>"plik"</code> w <code>mp3file</code> powodujespowoduje wywołanie metody <code>__setitem__</code> klasy <code>MP3FileInfo</code> (a nie słownika, czyli klasy <code>dict</code>). Z kolei metoda ta zauważa, że ustawiamy klucz <code>"plik"</code> z prawdziwą wartością (<code>item</code> jest prawdą w kontekście logicznym) i wywołuje <code>self.__parse</code>. Chociaż jeszcze nie analizowaliśmy działania metody <code>__parse</code>, możemy pona wyjściupodstawie wyjścia zobaczyć, że ustawia ona kilka innych kluczy jak <code>"album"</code>, <tt>"artysta"</tt>, <code>"genregatunek"</code>, <code>u"tytuł"</code> (w unikodzie, bo korzystamy z polskich znaków), <code>"rok"</code>, czy też <code>"comment"</code>.
# Kiedy zmienimy klucz <code>"plik"</code>, proces ten zostanie wykonany ponownie. Python wywoła <code>__setitem__</code>, który następnie wywoła <code>self.__parse</code>, a ten ustawi wszystkie inne klucze.
}}
Linia 87:
{{Nawigacja|Python|
[[../Klasa opakowująca UserDict|Klasa opakowująca <code>UserDict</code>]]|
[[../AtrybutyZaawansowane klasmetody specjalne/]]|
}}
{{Podświetl|py}}