Zanurkuj w Pythonie/Klasa opakowująca UserDict: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Linia 46:
 
# <code>clear</code> jest normalną metodą klasy; jest dostępna publicznie i może być wołana przez kogokolwiek w dowolnej chwili. Zauważmy, że w <code>clear</code>, jak we wszystkich metodach klas, pierwszym argumentem jest <code>self</code>. (Pamiętajmy, że nie dodajemy <code>self</code>, gdy wywołujemy metodę; Python robi to za nas.) Zwróćmy uwagę na podstawową cechę tej klasy opakowującej: przechowuje ona prawdziwy słownik w atrybucie <code>data</code> i definiuje wszystkie metody wbudowanego słownika, a w każdej z tych metod zwraca wynik identyczny do odpowiedniej metody słownika. (Gdybyśmy zapomnieli, metoda słownika <code>clear</code> czyści cały słownik kasując jego wszystkie klucze i wartości.)
# Metoda słownika o nazwie <code>copy</code> zwraca nowy słownik, który jest dokładną kopią oryginału (mający takie same pary klucz-wartość). Natomiast klasa <code>UserDict</code> nie może po prostu wywołać <code>self.data.copy</code>, ponieważ ta metoda zwraca wbydowanywbudowany słownik, a my chcemy zwrócić nową instancję klasy tej samej klasy, jaką ma <code>self</code>.
# Używamy atrybutu <code>__class__</code>, żeby sprawdzić, czy <code>self</code> jest obiektem klasy <code>UserDict</code>; jeśli tak, to jesteśmy w domu, bo wiemy, jak zrobić kopię <code>UserDict</code>: tworzymy nowy obiekt <code>UserDict</code> i przekazujemy mu słownik wyciągnięty z <code>self.data</code>, a wtedy możemy od razu zwrócić nowy obiekt <code>UserDict</code> nie wykonując nawet instrukcji <code>import copy</code> z następnej linii.
# Jeśli <code>self.__class__</code> nie jest <code>UserDict</code>-em, to <code>self</code> musi być jakąś podklasą <code>UserDict</code>-a, a w takim przypadku życie wymaga użycia pewnych trików. <code>UserDict</code> nie wie, jak utworzyć dokładną kopię jednego ze swoich potomków. W tym celu możemy np. znając atrybuty zdefiniowane w podklasie, wykonać na nich pętlę, podczas której kopiujemy każdy z tych atrybutów. Na szczęście istnieje moduł, który wykonuje dokładnie to samo, nazywa się on <code>copy</code>. Nie będziemy się tutaj wdawać w szczegóły (choć jest to wypaśny moduł, jeśli się w niego trochę wgłębimy). Wystarczy wiedzieć, że <code>copy</code> potrafi kopiować dowolne obiekty, a tu widzimy, jak możemy z niego skorzystać.