Zanurkuj w Pythonie/Klasa opakowująca UserDict: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
Nie podano opisu zmian |
|||
Linia 17:
# Metodę <tt>__init__</tt> nadpisaliśmy w klasie <tt>FileInfo</tt>. Zauważmy, że lista argumentów w klasie przodka jest różna niż w klasie potomka. Jest ok. Każda podklasa może mieć własny zbiór argumentów, pod warunkiem, że metody przodka będą wywoływane z poprawnymi argumentami. Tutaj klasa przodka posiada możliwość zdefiniowania początkowych wartości (dzięki przekazaniu słownika w argumencie <tt>dict</tt>), jednak której klasa <tt>FileInfo</tt> nie wykorzystuje.
# Python wspiera właściwości (zwane polami w Javie i PowerBuilderze). Właściwości to kawałki danych przechowywane w konkretnej instancji klasy. W tym przypadku, każda instancja klasy <tt>UserDict</tt> będzie posiadać właściwość <tt>data</tt>. By odwołać się do tego pola z kodu spoza klasy, dodajemy z przodu nazwę instancji - instancja.data, w ten sam sposób jak odwołujemy się do funkcji poprzez nazwę modułu w jakim się znajduje. By odwołać się do właściwości z wnętrza klasy, używamy <tt>self</tt>. Zazwyczaj wszystkie właściwości są inicjalizowane sensownymi wartościami w metodzie <tt>__init__</tt>. Jednak nie jest to wymagane, gdyż właściwości tak jak zmienne lokalne są tworzone gdy pierwszy raz przypisuje się do nich wartość.
# metoda <tt>update</tt> jest duplikatorem słownika: kopiuje wszystkie klucze i wartości z jednego słownika do drugiego. Ta metoda nie czyści słownika docelowego; jeśli były tam już jakieś klucze, te, które są w słowniku źródłowym zostaną nadpisane ale pozostałe się nie zmienią. Myśl o <tt>update</tt> jak o funkcji łączenia, nie kopiowania.
# tej składni mogłeś wcześniej nie widzieć (nie używałem jej w przykładach z tej książki). Jest to instrukcja <tt>if</tt> ale zamiast wciętego bloku zaczynającego się w następnej linii jest tu pojedyncza instrukcja w tej samej linii, za dwukropkiem. Jest to całkowicie poprawna składnia, będąca tylko skrótem, którego możesz używać, jeśli masz tylko jedną instrukcję w bloku (tak jak pojedyncza instrukcja bez klamer w C++). Możesz użyć tej składni albo wciętego kodu w następnych liniach, ale nie możesz użyć obu składni w tym samym bloku kodu.
Uwaga!
Java i Powerbuilder mogą przeciążać funkcje mające różne listy argumentów, na przykład klasa może mieć kilka metod z taką samą nazwą ale z różną liczbą argumentów lub z argumentami różnych typów. Inne języki (na przykład PL/SQL) obsługują nawet przeciążanie funkcji różniących się nazwą argumentu. Na przykład jedna klasa może mieć kilka metod z tą samą nazwą, tą samą liczbą argumentów tych samych typów ale inaczej nazwanych. Python nie ma żadnej z tych możliwości, nie ma w ogóle przeciążania funkcji. Metody są jednoznacznie definiowane przez ich nazwy i w danej klasie może być tylko jedna metoda o danej nazwie. Jeśli więc metoda potomna ma klasę <tt>__init__</tt>, to zawsze zasłoni ona metodę <tt>__init__</tt> klasy-przodka nawet, jeśli klasa pochodna definiuje ją z innymi argumentami. Ta uwaga stosuje się do wszystkich metod.
Uwaga!
Guido, pierwszy twórca Pythona, tak wyjaśnia zasłanianie funkcji: "Klasy pochodne mogą zasłonić metody klas bazowych. Ponieważ metody nie mają żadnych specjalnych przywilejów wołając inne metody tego samego obiektu, może okazać się, że metoda klasy bazowej wołająca inną metodę zdefiniowaną w tej samej klasie bazowej woła właściwie metodę klasy pochodnej która ją zasłania. (Dla programistów C++: wszystkie metody w Pythonie zachowują się jakby były wirtualne.)" Jeśli dla Ciebie nie ma to sensu (mnie osobiście strasznie wkurza), możesz to zignorować. Uważałem, że należy o tym wspomnieć.
Caution
Always assign an initial value to all of an instance's data attributes in the __init__ method. It will save you hours of debugging later, tracking down AttributeError exceptions because you're referencing uninitialized (and therefore non-existent) attributes.
|