Podsekcje

 
3.3 Specjalne nazwy metod

Klasy mogą implementować pewne operacje, które możemy następnie wywoływać przy użyciu specjalnej składni (np. używając operatorów arytmetycznych, odwołania do indeksu lub wykrojenia). Do ich definicji używa się metod o specjalnych nazwach. Mechanizm ten jest stosowanym w Pythonie podejściem do przeciążania operatorów, które pozwala definiować zachowanie klas w odniesieniu do operatorów języka. Na przykład, jeśli klasa definiuje metodę o nazwie __getitem__(), a x jest instancją tej klasy, wówczas zamiast x[i] możemy użyć x.__getitem__(i) Poza zaznaczonymi przypadkami, próba wykonania operacji przy braku odpowiedniej metody spowoduje wystąpienie wyjątku.  

Przy tworzeniu implementacji klasy emulującej typ wbudowany, należy ją ograniczyć do zakresu, który ma sens w odniesieniu do modelowanych obiektów. Na przykład, do niektórych sekwencji dobrze pasuje pobieranie pojedynczych elementów, lecz pobieranie wykrojeń może już nie mieć sensu (jako przykład może służyć interfejs NodeList w standardzie W3C DOM).

 
3.3.1 Podstawowa indywidualizacja

__init__(self[, ...])
Wywoływana przy tworzeniu instancji z argumentami przekazanymi konstruktorowi klasy. Jeśli klasa bazowa również ma metodę __init__(), to, aby zapewnić właściwe zainicjowanie bazowej części obiektu, metoda w klasie pochodnej (jeśli istnieje) musi ją jawnie wywołać, np. "KlasaBazowa.__init__(self, [argumenty...])". Na konstruktory nakłada się specjalne ograniczenie - nie mogą one zwracać wartości. Zwrócenie wartości przez konstruktor spowoduje wygenerowanie wyjątku TypeError.  

__del__(self)
Wywoływana tuż przed zniszczeniem instancji. Nazywana jest też destruktorem . Jeśli klasa bazowa również ma metodę __del__(), to, aby zapewnić właściwą finalizację bazowej części obiektu, metoda w klasie pochodnej (jeśli istnieje) musi ją jawnie wywołać. Zauważmy, że możliwe jest (choć zdecydowanie nie jest to zalecane) wstrzymanie usunięcia obiektu wewnątrz metody __del__() poprzez utworzenie nowego odwołania do niego. Metoda może być w takim przypadku wywołana później, tj. kiedy zostanie usunięte to odwołanie. Nie gwarantuje się wywołania metod __del__() dla obiektów, które istnieją w chwili zakończenia działania interpretera.  

Notka: "del x" nie wywołuje bezpośrednio x.__del__() -- instrukcja del zmniejsza tylko licznik odwołań do obiektu o jeden, zaś metoda __del__() jest wywoływana po osiągnięciu przez ten licznik wartości zero. W pewnych sytuacjach licznik może nigdy nie osiągnąć wartości zero. Do typowych należą: cykliczne odwołania pomiędzy obiektami (np. lista z dwukierunkowymi dowiązaniami lub struktura drzewiasta z odwołaniami do ojca i potomków); odwołanie do obiektu w ramce stosu funkcji, która wyłapała wyjątek (ramkę utrzymuje przy życiu stan stosu, zapisany w sys.exc_traceback); odwołanie do obiektu w ramce stosu, w której wystąpił nieobsłużony wyjątek podczas pracy interaktywnej (ramkę utrzymuje przy życiu stan stosu zapisany w sys.last_traceback). Pierwszej sytuacji można uniknąć tylko poprzez jawne przerwanie cykli, pozostałych zaś, poprzez zapisanie None w sys.exc_traceback lub sys.last_traceback. Cykliczne odwołania pomiędzy nieużywanymi obiektami są wykrywane, jeśli aktywny jest opcjonalny wykrywacz cykli (domyślnie jest on aktywny), jednak tworzące je obiekty mogą być usunięte tylko, jeśli nie są w ich ramach używane metody __del__() na poziomie Pythona. Aby uzyskać więcej informacji na temat sposobu obsługi metody __del__() przez wykrywacz cykli (oraz na temat wartości garbage), zajrzyj do dokumentacji modułu gc.

Ostrzeżenie: Ze względu na niepewne warunki, w których wykonywane są metody __del__(), wyjątki, które w nich wystąpią, są ignorowane, wypisywane jest jedynie ostrzeżenie na sys.stderr. Dodatkowo, jeśli metoda __del__() została wywołana jako odpowiedź na usunięcie modułu (np. przy zakończeniu pracy programu), inne obiekty globalne, do których chce się odwoływać __del__() mogą już być usunięte. Z tego powodu metody __del__() powinny wykonywać absolutne minimum operacji, wymaganych do zachowania zewnętrznych niezmienników. Poczynając od wersji 1.5, Python gwarantuje, że globalne obiekty modułu, których nazwy rozpoczynają się pojedynczym podkreśleniem, są usuwane przed wszystkimi innymi; jeśli nie istnieją inne odwołania do nich, może to pomóc w zagwarantowaniu, że zaimportowane moduły są nadal dostępne w chwili wywołania metody __del__().

__repr__(self)
Wywoływana przez wbudowaną funkcję repr() oraz przy konwersjach napisowych (odwrócone apostrofy) do wygenerowania "oficjalnej" reprezentacji napisowej obiektu. Jeśli to możliwe, napis powinien być poprawnym wyrażeniem w Pythonie, po przewartościowaniu którego otrzymamy obiekt o tej samej wartości (w odpowiednim środowisku). Jeśli nie jest możliwe zapisanie wartości w takiej postaci, zwracany napis powinien wyglądać następująco: "<...użyteczny opis...>". Zwracana wartość musi być obiektem napisowym. Jeśli klasa implementuje metodę __repr__(), jednak nie implementuje metody __str__(), wówczas metoda __repr__() stosowana jest w zastępstwie __str__() w sytuacjach, w których potrzebna jest "informacyjną" reprezentacja instancji klasy.

Metoda ta jest zwykle używana podczas debugowania, ważne więc, aby reprezentacja zawierała pełnię informacji o obiekcie i aby była jednoznaczna.  

__str__(self)
Wywoływana przez wbudowaną funkcję str() oraz instrukcję print celem wygenerowania napisu zawierającego "informacyjną" reprezentację obiektu. Różnica w stosunku do __repr__() polega na tym, że napis nie musi być poprawnym wyrażeniem w Pythonie, dopuszczalna jest np. forma czytelniejsza lub bardziej zwięzła. Zwracana wartość musi być typu napisowego.

__lt__(self, inny)
__le__(self, inny)
__eq__(self, inny)
__ne__(self, inny)
__gt__(self, inny)
__ge__(self, inny)
Dodano w wersji 2.1. Są to tzw. metody "porównań szczegółowych", a wywoływane są przy użyciu operatorów porównania przed wywołaniem opisanej poniżej metody __cmp__(). Zależność pomiędzy operatorami i nazwami metod przedstawia się następująco: x<y wywołuje x.__lt__(y), x<=y wywołuje x.__le__(y), x==y wywołuje x.__eq__(y), x!=y oraz x<>y wywołują x.__ne__(y), x>y wywołuje x.__gt__(y), x>=y wywołuje x.__ge__(y). Metody te mogą zwracać dowolne wartości, lecz jeśli operator porównania zostanie użyty w kontekście logicznym, zwracana wartość powinna dać się zinterpretować jako wartość logiczna, w przeciwnym bowiem wypadku wystąpi wyjątek TypeError. Zgodnie z konwencją False jest używane w znaczeniu fałszu, zaś True - w znaczeniu prawdy.

Pomiędzy operatorami porównań nie występują żadne zależności mające charakter ogólny. Prawdziwość porównania x==y nie musi pociągać za sobą nieprawdziwości porównania x!=y. Analogicznie, przy definiowaniu metody __eq__ należy również zdefiniować __ne__, tak aby operatory zachowywały się w oczekiwany sposób.

Nie istnieją osobne wersje powyższych metod z argumentami zamienionymi miejscami (używanymi, jeśli lewy argument nie obsługuje operacji, natomiast prawy ją obsługuje); jednak metody __lt__() i __gt__() stanowią wzajemnie swoje odwrócenie, podobnie jest z metodami __le__() i __ge__() oraz __eq__() i __ne__().

Argumenty porównań szczegółowych nie są nigdy uzgadniane. Jeśli metoda porównania szczegółowego nie implementuje operacji dla podanej pary argumentów, może wygenerować wyjątek NotImplemented.

__cmp__(self, inny)
Wywoływana przy operacjach porównań, jeśli porównanie szczegółowe (patrz wyżej) nie jest zdefiniowane. Jeśli self < inny, funkcja powinna zwrócić całkowitą liczbę ujemną, jeśli self == inny - zero, jeśli zaś self > inny - całkowitą liczbę dodatnią. Jeśli klasa nie definiuje operacji __cmp__(), __eq__(), ani __ne__(), jej instancje są porównywane według tożsamości ("adresów") obiektów. Ważne uwagi na temat tworzenia obiektów, które obsługują własne operacje porównań i mogą być używane jako klucze w słownikach, odnajdziesz w opisie metody __hash__(). (Uwaga: ograniczenie, polegające na tym, że wyjątki nie są propagowane przez metodę __cmp__() zostało zniesione w Pythonie 1.5.)  

__rcmp__(self, inny)
Zmieniono w wersji 2.1: Już nieobsługiwane.

__hash__(self)
Wywoływana dla obiektów kluczy przy operacjach słownikowych i przez wbudowaną funkcję hash() . Powinna zwrócić 32-bitową liczbę całkowitą, użyteczną jako wartość rozsiewająca przy operacjach słownikowych. Jest tylko jedno ograniczenie: dla obiektów, które przy porównaniu są równe, musi zostać zwrócona ta sama wartość; zaleca się powiązanie w jakiś sposób (np. przy użyciu alternatywy wykluczającej) wartości hash dla tych komponentów obiektów, które są wykorzystywane również przy porównywaniu. Jeśli dla klasy nie zdefiniowano metody __cmp__(), nie należy również definiować metody __hash__(). Jeśli zdefiniowana zostanie __cmp__() lub __eq__(), ale nie __hash__(), instancje klasy nie będą mogły być wykorzystywane jako klucze w słowników. Jeśli klasa definiuje obiekty zmienne i zdefiniowana jest metoda __cmp__() lub __eq__(), nie należy definiować metody __hash__(), gdyż implementacja słownika wymaga, aby wartości hash jego kluczy były niezmienne (jeśli wartość hash obiektu ulegnie zmianie, znajdzie się on w niewłaściwym kubełku tablicy rozsiewanej).  

__nonzero__(self)
Wywoływana w celu sprawdzenia wartości logicznej obiektu oraz przez wbudowaną funkcję bool(); powinna zwrócić False lub True, ew. ich liczbowe odpowiedniki, 0 lub 1. Jeśli metoda ta nie jest zdefiniowana, wywoływana jest metoda __len__(). Jeśli klasa nie definiuje i tej metody, przyjmuje się, że wartością logiczną wszystkich jej instancji jest prawda.  

__unicode__(self)
Wywoływana przez wbudowaną funkcję unicode() , powinna zwrócić obiekt Unicode. Jeśli metoda nie jest zdefiniowana, zamiast jej wywołania wykonywana jest konwersja napisowa, zaś jej wynik jest następnie konwertowany do Unicode przy wykorzystaniu domyślnego kodowania w środowisku wykonawczym.

 
3.3.2 Indywidualizacja dostępu do atrybutów

Poprzez zdefiniowanie opisanych poniżej metod możliwa jest zmiana semantyki dostępu do atrybutów (użycia, przypisania lub usunięcia x.nazwa dla instancji klas).

__getattr__(self, nazwa)
Wywoływana, jeśli przy odwołaniu do atrybutu nie można go odnaleźć w zwykły sposób, tj. jeśli atrybut nie istnieje w instancji, ani w drzewie klas obiektu self. Parametr nazwa zawiera nazwę atrybutu. Metoda powinna zwrócić wartość atrybutu lub wygenerować wyjątek AttributeError.

Zwróćmy uwagę, że jeśli atrybut zostanie odnaleziony w zwykły sposób, metoda __getattr__() nie będzie wywołana. (Występuje tu celowa asymetria pomiędzy __getattr__() a __setattr__().) Jest tak zarówno ze względu na wydajność, jak i dlatego, że w przeciwnym wypadku __setattr__() nie mogłaby w żaden sposób uzyskać dostępu do innych atrybutów instancji. W przypadku zmiennych instancji można zasymulować pełną kontrolę, nie wstawiając do słownika atrybutów instancji żadnych wartości (wstawiając je natomiast wewnątrz innego obiektu). Sposób przejęcia całkowitej kontroli nad dostępem do atrybutów instancji przy klasach w nowym stylu opisano w dalszej części, dotyczącej metody __getattribute__().  

__setattr__(self, nazwa, wartość)
Wywoływana przy operacji przypisania do atrybutu. Jest ona używana w miejsce zwykłego mechanizmu, tj. zapisania wartości w słowniku instancji. Parametr nazwa jest nazwą atrybutu, wartość jest przypisywaną mu wartością.

Aby dokonać przypisania do atrybutu instancji wewnątrz tej metody, nie należy używać zwykłej instrukcji przypisania ("self.nazwa = wartość"), gdyż spowodowałoby to rekurencyjne wywołanie tej samej metody. Zamiast tego należy bezpośrednio wstawić wartość do słownika atrybutów instancji, np. "self.__dict__[nazwa] = wartość". W przypadku klas w nowym stylu, zamiast bezpośredniego odwoływania się do słownika atrybutów należy wywołać metodę klasy bazowej o tej samej nazwie, np. "obiekt.__setattr__(self, nazwa, wartość)".  

__delattr__(self, nazwa)
Używana podobnie jak __setattr__(), lecz w odniesieniu do usunięcia atrybutu, zamiast do przypisania. Metoda powinna być implementowana tylko, jeśli "del obj.nazwa" ma jakiś sens.

 
3.3.2.1 Rozszerzony dostęp do atrybutów przy klasach w nowym stylu

Opisane poniżej metody występują wyłącznie w obiektach w nowym stylu.

__getattribute__(self, nazwa)
Metoda jest wywoływana bezwarunkowo w celu realizacji dostępu do atrybutu instancji klasy. Jeśli klasa implementuje również metodę __getattr__, nie będzie ona nigdy wywoływana (chyba, że zostanie wywołana jawnie). Wynikiem działania metody powinna być (wyliczona) wartość atrybutu o podanej nazwie lub wygenerowanie wyjątku AttributeError. Aby uniknąć nieskończonej rekurencji przy wywołaniach tej metody, wewnątrz jej implementacji należy odwoływać się do atrybutów obiektu wyłącznie poprzez wywołanie metody o tej samej nazwie z klasy bazowej, np.: "obiekt.__getattribute__(self, nazwa)".

 
3.3.2.2 Implementowanie deskryptorów

Poniższe metody mają zastosowanie tylko w przypadkach, gdy instancja klasy zawierającej metodę (tzw. klasa deskryptora) pojawia się w słowniku innej klasy w nowym stylu, znanej jako klasa właściciela. W przedstawionych przykładach określenie "atrybut" odnosi się do atrybutu, którego nazwa jest kluczem własności w słowniku __dict__ klasy właściciela.

__get__(self, instancja, właściciel)
Wywoływana w celu uzyskania atrybutu klasy właściciela (dostęp do atrybutu klasy) lub instancji tej klasy (dostęp do atrybutu instancji). Argument właściciel odnosi się zawsze do klasy właściciela, natomiast instancja jest instancją poprzez którą wystąpił dostęp do atrybutu lub ma wartość None, jeśli dostęp do atrybutu występuje poprzez klasę właściciel. Wynikiem działania metody powinna być (wyliczona) wartość atrybutu lub wygenerowanie wyjątku AttributeError.

__set__(self, instancja, wartość)
Wywoływana w celu ustawienia atrybutu instancji instancja klasy, do której należy metoda, na wartość wartość.

__delete__(self, instancja)
Wywoływana w celu usunięcia atrybutu instancji instancja klasy, do której należy metoda, na wartość wartość.

 
3.3.2.3 Używanie deskryptorów

W ogólnym przypadku deskryptor jest atrybutem obiektu definiującym "zachowanie dowiązania", tj. takim, do którego dostęp jest kontrolowany przez metody deskryptora o nazwach: __get__(), __set__() i __delete__(). Jeśli obiekt implementuje którąkolwiek z tych metod, wówczas określa się go mianem deskryptora.

Domyślnym zachowaniem przy dostępie do atrybutu jest jego pobranie, ustawienie lub usunięcie ze słownika powiązanego z obiektem. Na przykład zapis a.x powoduje uruchomienie łańcucha poszukiwań, rozpoczynającego się od a.__dict__['x'], po którym następuje type(a).__dict__['x'] oraz ciąg analogicznych odwołań dla wszystkich klas bazowych klasy type(a) z pominięciem metaklas.

Jeśli jednak odnaleziona wartość jest obiektem definiującym jedną z metod deskryptora, domyślne zachowanie może zostać zastąpione wywołaniem odpowiedniej metody. Miejsce w łańcuchu poszukiwań, w którym używane są deskryptory, zależy od tego, które metody deskryptora zostały zdefiniowane i w jaki sposób są wywoływane. Należy przy tym podkreślić, że deskryptory są używane tylko przy obiektach lub klasach w nowym stylu (będących pochodnymi klasy object() lub type()).

Punktem wyjścia dla użycia deskryptora jest dowiązanie, a.x. Sposób, w jaki ustalane są argumenty, zależy od tego, czym jest a:

Bezpośrednie wywołanie
Najprostsze i najrzadziej spotykane wywołanie występuje w przypadku, gdy kod użytkownika bezpośrednio wywołuje metodę deskryptora: x.__get__(a).

Dowiązanie do instancji
Przy dowiązaniu do instancji klasy w nowym stylu zapis a.x jest przekształcany na wywołanie: type(a).__dict__['x'].__get__(a, type(a)).

Dowiązanie do klasy
Przy dowiązaniu do klasy w nowym stylu, zapis A.x jest przekształcany na wywołanie: A.__dict__['x'].__get__(None, A).

Dowiązanie do klasy super
Jeśli a jest instancją klasy super, wówczas dowiązanie super(B, obiekt).m() powoduje wyszukanie wśród wartości obj.__class__.__mro__ klasy bazowej A bezpośrednio poprzedzającej B, a następnie wywołanie deskryptora przy użyciu wyrażenia: A.__dict__['m'].__get__(obiekt, A).

W przypadku dowiązania do instancji priorytet użycia deskryptorów, w stosunku do innych metod dostępu do atrybutu, zależy od tego, jakie implementuje on metody. Deskryptory opisujące dane definiują metody __get__() oraz __set__(). Deskryptory nie opisujące danych definiują wyłącznie metodę __get__(). Deskryptory opisujące dane biorą zawsze górę nad ponowną definicją atrybutu w słowniku instancji. Z drugiej strony, deskryptory nie opisujące danych mogą zostać nadpisane przez instancje.

Metody Pythona (łącznie ze zdefiniowanymi przy użyciu staticmethod() lub classmethod()) są implementowane jako deskryptory nie opisujące danych. W związku z tym instancje mogą przedefiniowywać i nadpisywać metody, co pozwala różnicować zachowanie poszczególnych instancji tej samej klasy.

Funkcja property() jest zaimplementowana przy użyciu deskryptora opisującego dane, w związku z czym instancje nie mogą modyfikować jej zachowania.

 
3.3.2.4 __slots__

Domyślnie z każdą instancją klasy w starym jak i w nowym stylu związany jest słownik przechowujący jej atrybuty. Powoduje to niegospodarne wykorzystanie pamięci w przypadku obiektów mających niewielką ilość zmiennych poziomu instancji, szczególnie dolegliwe przy tworzeniu dużej liczby instancji.

Domyślne zachowanie można zmienić poprzez ustawienie atrybutu wewnątrz definicji klasy w nowym stylu. Przypisanie atrybutowi __slots__ sekwencji nazw zmiennych poziomu instancji powoduje przydzielenie w każdej instancji ilości miejsca dokładnie odpowiadającej liczbie zmiennych. Oszczędność miejsca polega na uniknięciu tworzenia słownika __dict__ dla każdej instancji.

__slots__
Zmienna poziomu klasy, której można przypisać napis, obiekt iterowalny lub sekwencję napisów, które są nazwami zmiennych używanych przez instancje. Zdefiniowanie atrybutu __slots__ wewnątrz klasy w nowym stylu powoduje zarezerwowanie miejsca na zadeklarowane miejsce i zapobiega automatycznemu tworzeniu atrybutów __dict__ i __weakref__ przy każdej instancji. Dodano w wersji 2.2.

Uwagi na temat użycia atrybutu __slots__

 
3.3.3 Indywidualizacja tworzenia klas

Domyślnie klasy w nowym stylu są tworzone przy użyciu funkcji type(). Definicja klasy jest umieszczana w odrębnej przestrzeni nazw, zaś do nazwy klasy dowiązywany jest wynik wywołania type(nazwa, bazowe, słownik).

Jeśli na etapie odczytywania definicji klasy, zdefiniowana jest zmienna __metaclass__, to zamiast funkcji type() zostanie wywołana wartość tej zmiennej. Pozwala to na tworzenie klas lub funkcji monitorujących lub zmieniających proces tworzenia klas. Do możliwych zmian należą:

__metaclass__
Wartością zmiennej może być dowolny obiekt wywoływalny, pobierający argumenty nazwa, bazowe oraz słownik. Obiekt wywoływany jest w zastępstwie wbudowanej funkcji type() na etapie tworzenia klasy. Dodano w wersji 2.2.

Właściwa metaklasa jest wybierana zgodnie z poniższymi regułami ustalającymi priorytety postępowania:

Potencjalne obszary zastosowań metaklas są nieograniczone. Wykorzystane już pomysły obejmują rejestrowanie zdarzeń w dzienniku, sprawdzanie interfejsu, automatyczne delegowanie, automatyczne tworzenie właściwości, klasy pośredniczące, szkielety, jak też automatyczne synchronizowanie/blokowanie zasobów.

 
3.3.4 Emulowanie obiektów wywoływalnych

__call__(self[, argumenty...])
Wywoływana przy operacji "wywołania" instancji jak funkcji; jeśli jest ona zdefiniowana, to x(arg1, arg2, ...) jest odpowiednikiem x.__call__(arg1, arg2, ...).  

 
3.3.5 Emulowanie typów kontenerowych

Poniższe metody mogą być zdefiniowane w celu zaemulowania obiektów kontenerowych. Kontenery są zwykle sekwencjami (np. listy czy krotki) lub odwzorowaniami (np. słowniki) lecz obiekty mogą również reprezentować również inne kontenery. Pierwszy zbiór metod jest używany do emulowania albo sekwencji albo odwzorowań; różnica polega na tym, że w przypadku sekwencji dopuszczalnymi kluczami powinny być wartości całkowite k, takie, że 0 <= k < N, gdzie N jest długością sekwencji, lub też obiekty wykrojenia, definiujące zakresy elementów (w celu zachowania zgodności wstecz można również zdefiniować metodę __getslice__() (patrz niżej), obsługującą proste wykrojenia, bez obsługi wykrojeń złożonych). W przypadku odwzorowań zaleca się również udostępnianie metod keys(), values(), items(), has_key(), get(), clear(), setdefault(), iterkeys(), itervalues(), iteritems(), pop(), popitem(), copy() oraz update() z zachowaniem semantyki zbliżonej do tej, która obowiązuje przy standardowych obiektach słownikowych Pythona. Moduł UserDict oferuje klasę DictMixin, pomocną przy tworzeniu tych metod w oparciu o zaimplementowany zestaw metod bazowych: __getitem__(), __setitem__(), __delitem__() oraz keys(). Podobnie, sekwencje zmienne powinny udostępniać metody append(), count(), index(), extend(), insert(), pop(), remove(), reverse() oraz sort(), o działaniu zbliżonym do standardowych obiektów listowych Pythona. Ponadto, typy sekwencyjne powinny implementować operacje dodawania (w znaczeniu doklejenia) oraz mnożenia (w znaczeniu powtórzenia) poprzez definicje opisanych poniżej metod __add__(), __radd__(), __iadd__(), __mul__(), __rmul__() oraz __imul__(). Nie należy jednak w takich przypadkach definiować __coerce__(), ani innych metod, odpowiadających wyłącznie operatorom liczbowym. Zaleca się, aby metodę __contains__() implementowały zarówno odwzorowania, jak i sekwencje, co pozwala na efektywne użycie operatora in. W przypadku odwzorowań in powinien być odpowiednikiem metody has_key(). Przy sekwencjach powinien on powodować przeszukanie kolejnych jej wartości. Zaleca się ponadto, aby zarówno odwzorowania, jak i sekwencje implementowały metodę __iter__(), pozwalającą na efektywne przebieganie (iterowanie) przez elementy kontenera. Przy odzworowaniach metoda __iter__() powinna być równoważnikiem metody iterkeys(). Przy sekwencjach powinna ona przebiegać przez kolejne elementy sekwencji.     

__len__(self)
Wywoływana przy użyciu wbudowanej funkcji len() . Powinna zwrócić długość obiektu jako nieujemną liczbę całkowitą. Ponadto, jeśli dla obiektu nie zdefiniowano metody __nonzero__(), a metoda __len__() zwróci wartość zero, to za wartość logiczną obiektu uznaje się prawdę.  

__getitem__(self, klucz)
Wywoływana przy obliczaniu wartości self[klucz]. W przypadku typów sekwencyjnych powinny być akceptowane klucze całkowitoliczbowe oraz obiekty wykrojenia. Zwróćmy uwagę, że specjalna interpretacja indeksów ujemnych (jeśli klasa ma emulować typ sekwencyjny) należy do samej metody __getitem__(). Jeśli klucz jest niewłaściwego typu, może zostać wygenerowany wyjątek TypeError; jeśli wartość nie należy do zbioru dopuszczalnych indeksów sekwencji (po specjalnej interpretacji wartości ujemnych), powinien zostać wygenerowany wyjątek IndexError. Notka: Działanie instrukcji for zależy od faktu, że przy niedopuszczalnych indeksach zostanie wygenerowany wyjątek IndexError, gdyż w ten sposób wykrywany jest koniec sekwencji.

__setitem__(self, klucz, wartość)
Wywoływana przy przypisaniu do self[wartość]. Odnoszą się do niej te same uwagi, co do __getitem__(). Metoda powinna być implementowana tylko w odniesieniu do obiektów odwzorowawczych, które pozwalają na podmienianie wartości przypisanych kluczom ew. na dodawanie nowych kluczy oraz przy sekwencjach, których elementy można podmieniać. Przy niepoprawnych wartościach klucza powinny być generowane te same wyjątki, co w przypadku metody __getitem__().

__delitem__(self, klucz)
Wywoływana przy usunięciu self[klucz]. Odnoszą się do niej te same uwagi, co do __getitem__(). Metoda powinna być implementowana tylko w odniesieniu do obiektów odwzorowawczych, które pozwalają na usuwanie kluczy oraz przy sekwencjach, których elementy można usuwać. Przy niepoprawnych wartościach klucza powinny być generowane te same wyjątki, co w przypadku metody __getitem__().

__iter__(self)
Wywoływana, kiedy potrzebny jest iterator dla podanego kontenera. Metoda powinna zwrócić nowy obiekt iteratora, który pozwala na iterowanie po wszystkich obiektach kontenera. W przypadku odwzorowań iterowanie powinno się odbywać po jego kluczach, a odpowiedni iterator powinien być również dostępny za pośrednictwem metody iterkeys().

Do zaimplementowania tej metody potrzebne są również obiekty iteratorów, które powinny zwracać same siebie. Aby uzyskać więcej informacji na temat obiektów iteratorów, zajrzyj do sekcji "Typy iteratorów" w pozycji Podręcznik programisty Pythona - opis biblioteki standardowej.

Operatory sprawdzania przynależności (in oraz not in) są normalnie implementowane jako iteracja przez elementy sekwencji. Obiekty kontenerowe mogą jednak dostarczać bardziej efektywnych implementacji, definiując poniższą specjalną metodę, która nie wymaga jednocześnie, aby obiekt był sekwencją.

__contains__(self, element)
Wywoływana jako implementacja operatorów sprawdzania przynależności. Powinna zwrócić prawdę, jeśli element należy do self, w przeciwnym wypadku zaś fałsz. W przypadku obiektów odwzorowawczych powinny być brane pod uwagę same klucze odwzorowania, zamiast par klucz-wartość.

 
3.3.6 Dodatkowe metody, służące emulowaniu typów sekwencyjnych

Poniższe opcjonalne metody mogą zostać zdefiniowane celem dokładniejszej emulacji obiektów sekwencyjnych. W przypadku sekwencji niezmiennych należy zdefiniować co najwyżej metodę __getslice__(); przy sekwencjach zmiennych można zdefiniować wszystkie trzy metody.

__getslice__(self, i, j)
Przestarzałe od wersji 2.0. Dopuszcza się obiekty wykrojenia jako parametry metody __getitem__().

Wywoływana przy obliczaniu wyrażenia self[i:j]. Zwracany obiekt powinien być tego samego typu, co self. Brakujące i lub j zastępowane jest odpowiednio przez zero i sys.maxint. Jeśli w wykrojeniu zostaną użyte indeksy ujemne, do odpowiednich indeksów jest dodawana długość sekwencji. Jeśli instancja nie implementuje metody __len__(), generowany jest wyjątek AttributeError. Nie daje się żadnych gwarancji, że indeksy po dokonaniu korekty nie będą nadal ujemne. Ponadto indeksy większe od długości sekwencji nie są modyfikowane. Przy braku metody __getslice__() utworzony zostanie obiekt wykrojenia, a następnie przekazany do metody __getitem__().

__setslice__(self, i, j, sekwencja)
Wywoływana przy przypisaniu do self[i:j], Do i i j odnoszą się te same uwagi, co przy metodzie __getslice__().

Metoda ta jest przestarzała. Przy braku metody __setslice__() lub w przypadku użycia rozszerzonego wykrojenia o postaci self[i:j:k] zamiast wywołania __setslice__() tworzony jest obiekt wykrojenia, a następnie przekazywany do metody __setitem__().

__delslice__(self, i, j)
Wywoływana przy operacji usunięcia self[i:j]. Do i i j odnoszą się te same uwagi, co przy metodzie __getslice__(). Metoda ta jest przestarzała. Przy braku metody __delslice__() lub w przypadku użycia rozszerzonego wykrojenia o postaci self[i:j:k] zamiast wywołania __delslice__() tworzony jest obiekt wykrojenia, a następnie przekazywany do metody __delitem__().

Powyższe metody są wywoływane tylko, jeśli zostało użyte pojedyncze wykrojenie z jednym dwukropkiem oraz metoda wykrojenia jest dostępna. W przypadku operacji wykrojenia opartej na rozszerzonym zapisie wykrojenia lub w przypadku braku odpowiedniej metody wywoływana jest metoda __getitem__(), __setitem__() lub __delitem__() z obiektem wykrojenia jako argumentem.

Poniższy przykład pokazuje, w jaki sposób można przygotować program lub moduł tak, aby był zgodny z wcześniejszymi wersjami Pythona (przy założeniu, że metody __getitem__(), __setitem__() oraz __delitem__() dopuszczają obiekty wykrojenia jako argumenty):

class MojaKlasa:
    ...
    def __getitem__(self, indeks):
        ...
    def __setitem__(self, indeks, wartość):
        ...
    def __delitem__(self, indeks):
        ...

    if sys.version_info < (2, 0):
        # Metody nie będą zdefiniowane, jeśli wersja jest wcześniejsza od 2.0

        def __getslice__(self, i, j):
            return self[max(0, i):max(0, j):]
        def __setslice__(self, i, j, seq):
            self[max(0, i):max(0, j):] = seq
        def __delslice__(self, i, j):
            del self[max(0, i):max(0, j):]
    ...

Zwróćmy uwagę na wywołania funkcji max(); są one potrzebne ze względu na obsługiwanie indeksów ujemnych przed wywoływaniem metod __*slice__(). W przypadku użycia indeksów ujemnych metody __*item__() otrzymują je bez zmian, jednak __*slice__() otrzymują zmodyfikowane wersje. Do każdego indeksu dodawana jest długość sekwencji (co nie musi jednak dawać wartości nieujemnej); jest to zwyczajowy sposób obsługi ujemnych indeksów przez wbudowane typy sekwencyjne i przyjmuje się, że metody __*item__() zachowują się podobnie. Jednak, ponieważ powinny one już to robić, nie można przekazywać ujemnych indeksów; muszą one przed przekazaniem do metod __*item__() zostać zawężone do granic sekwencji. Wywołanie max(0, i) w wygodny sposób tworzy poprawną wartość.

 
3.3.7 Emulowanie typów liczbowych

Opisane poniżej metody mogą być wykorzystywane do emulacji obiektów liczbowych. Jeśli obiekty danego typu nie obsługują pewnych operacji (np. operacji bitowych w przypadku liczb niecałkowitych), odpowiadające im metody należy pozostawić niezdefiniowane.

__add__(self, inny)
__sub__(self, inny)
__mul__(self, inny)
__floordiv__(self, inny)
__mod__(self, inny)
__divmod__(self, inny)
__pow__(self, inny[, modulo])
__lshift__(self, inny)
__rshift__(self, inny)
__and__(self, inny)
__xor__(self, inny)
__or__(self, inny)
Metody te wywoływane są jako implementacje dwuargumentowych operacji arytmetycznych (+, -, *, //, %, divmod() , pow() , **, <<, >>, &, ^, |). Na przykład, aby obliczyć wartość wyrażenia x+y, gdzie x jest instancją klasy ze zdefiniowaną metodą __add__(), wywoływane jest x.__add__(y). Metoda __divmod__() powinna być odpowiednikiem użytych jednocześnie metod __floordiv__() i __mod__(). Nie powinna ona być powiązana z opisaną dalej metodą __truediv__(). Zwróćmy uwagę, że jeśli obsługiwana ma być trójargumentowa postać wbudowanej funkcji pow() , to definicja metody __pow__() powinna dopuszczać opcjonalny trzeci argument.

__div__(self, inny)
__truediv__(self, inny)
Metody te wywoływane są jako implementacje operacji dzielenia (/). Jeśli aktywna jest cecha __future__.division, następuje użycie metody __truediv__(), w przeciwnym wypadku używana jest __div__(). Jeśli zdefiniowana jest tylko jedna z tych metod, to obiekt nie będzie obsługiwał dzielenia w kontekście odmiennym od tego, w którym jest ona stosowana, (tzw. nie jest wywoływana w zastępstwie druga metoda). W tym przypadku generowany jest wyjątek TypeError.

__radd__(self, inny)
__rsub__(self, inny)
__rmul__(self, inny)
__rdiv__(self, inny)
__rtruediv__(self, inny)
__rfloordiv__(self, inny)
__rmod__(self, inny)
__rdivmod__(self, inny)
__rpow__(self, inny)
__rlshift__(self, inny)
__rrshift__(self, inny)
__rand__(self, inny)
__rxor__(self, inny)
__ror__(self, inny)
Metody te są wywoływane jako implementacje dwuargumentowych operacji arytmetycznych (+, -, *, /, %, divmod() , pow() , **, <<, >>, &, ^, |) z operandami zamienionymi miejscami. Ich wywołanie następuje tylko wtedy, gdy lewy operand nie obsługuje określonej operacji. Na przykład, aby obliczyć wartość wyrażenia x-y, gdzie y jest instancją klasy ze zdefiniowaną metodą __rsub__(), wywoływane jest y.__rsub__(x). Zwróćmy uwagę, iż przy trójargumentowym pow() nie nastąpi próba wywołania __rpow__() (reguły uzgadniania stałyby się zbyt skomplikowane).

__iadd__(self, inny)
__isub__(self, inny)
__imul__(self, inny)
__idiv__(self, inny)
__itruediv__(self, inny)
__ifloordiv__(self, inny)
__imod__(self, inny)
__ipow__(self, inny[, modulo])
__ilshift__(self, inny)
__irshift__(self, inny)
__iand__(self, inny)
__ixor__(self, inny)
__ior__(self, inny)
Funkcje te są wywoływane jako implementacje operacji modyfikacji arytmetycznych (+=, -=, *=, /=, %=, **=, <<=, >>=, &=, ^=, |=). Metody powinny starać się wykonywać operacje na miejscu (modyfikując self) i zwracać wynik (którym może, ale nie musi być self). Jeśli dana metoda nie jest zdefiniowana, operacja modyfikacji wykonywana jest przy użyciu odpowiedniej zwykłej metody. Na przykład, aby obliczyć wartość wyrażenia x+=y, gdzie x jest instancją klasy ze zdefiniowaną metodą __iadd__(), wywoływane jest x.__iadd__(y). Jeśli x jest instancją klasy bez metody __iadd(), brane są pod uwagę metody x.__add__(y) oraz y.__radd__(x), podobnie, jak przy wyrażeniu x+y.

__neg__(self)
__pos__(self)
__abs__(self)
__invert__(self)
Wywoływane jako implementacje jednoargumentowych operacji arytmetycznych (-, +, abs() oraz ~).

__complex__(self)
__int__(self)
__long__(self)
__float__(self)
Wywoływane przez wbudowane funkcje complex() , int() , long() , oraz float() . Powinny zwracać wartości odpowiednich typów.

__oct__(self)
__hex__(self)
Wywoływane przez wbudowane funkcje oct() oraz hex() . Powinny zwracać wartości napisowe.

__coerce__(self, inny)
Wywoływana przy arytmetyce liczbowej z argumentami różnych typów. Powinna zwrócić krotkę dwuelementową, zawierającą wartości self i inny, przekształcone do wspólnego typu liczbowego, lub None, jeśli konwersja nie jest możliwa. Jeśli wspólny typ ma być taki sam, jak typ argumentu inny, wygodnie jest zwrócić None, gdyż interpreter spróbuje dokonać uzgodnienia również na drugim argumencie (z drugiej strony, jeśli nie można zmienić implementacji drugiego typu, czasem warto przeprowadzić jego konwersję przy pierwszym). Zwrócenie wartości NotImplemented jest równoważne zwróceniu None.

 
3.3.8 Reguły uzgadniania

W przeszłości sekcja ta opisywała reguły uzgadniania. Wraz z rozwojem języka reguły te stały się jednak zbyt złożone, aby je precyzyjnie zdefiniować, zaś szczegółowe dokumentowanie zachowania konkretnej wersji jednej implementacji nie byłoby zbyt użyteczne. Zamiast tego poniżej zamieszczono więc pewne wskazówki dotyczące uzgadniania. W Pythonie 3.0 uzgadnianie nie będzie obsługiwane.

Zajrzyj do Informacji na temat tej publikacji... aby pomóc w jej rozwoju.