Chociaż przyczyna jest głównie historyczna, w Pythonie istnieją pewne osobliwości, lenktóre sprawiają, że użycie funkcji zamiast metody jest właściwe.
Niektóre operacje w Pythonie są zaimplementowane na przykład jako metody, list.indexa dict.appendpodczas gdy inne są zaimplementowane jako wywołania i metody magiczne, na przykład stri iteri reversed. Te dwie grupy różnią się wystarczająco, więc inne podejście jest uzasadnione:
- Są pospolite.
str, intI przyjaciele są typy. Bardziej sensowne jest wywołanie konstruktora.
- Implementacja różni się od wywołania funkcji. Na przykład
itermoże wywołać, __getitem__jeśli __iter__nie jest dostępny, i obsługuje dodatkowe argumenty, które nie pasują do wywołania metody. Z tego samego powodu it.next()został zmieniony next(it)w ostatnich wersjach Pythona - ma to większy sens.
- Niektórzy z nich są bliskimi krewnymi operatorów. Istnieje składnia do wywoływania
__iter__i __next__- to się nazywa forpętla. Dla spójności funkcja jest lepsza. I to sprawia, że jest to lepsze dla niektórych optymalizacji.
- Niektóre funkcje są po prostu w pewien sposób zbyt podobne do innych -
reprdziała jak strdziała. Mając str(x)kontra x.repr()byłoby mylące.
- Na przykład niektóre z nich rzadko korzystają z rzeczywistej metody implementacji
isinstance.
- Niektórzy z nich są faktycznymi operatorami,
getattr(x, 'a')to inny sposób działania x.ai getattrmają wiele z wyżej wymienionych cech.
Osobiście nazywam pierwszą grupę metodą metodyczną, a drugą grupę operacyjną. To niezbyt dobre rozróżnienie, ale mam nadzieję, że jakoś pomoże.
Powiedziawszy to, lennie pasuje dokładnie do drugiej grupy. Jest bardziej zbliżony do operacji z pierwszej, z tą różnicą, że jest o wiele bardziej powszechny niż prawie każda z nich. Ale jedyne, co robi, to dzwonienie __len__i jest bardzo blisko L.index. Istnieją jednak pewne różnice. Na przykład __len__może zostać wywołany w celu implementacji innych funkcji, na przykład bool, jeśli metoda została wywołana, lenmożesz zerwać bool(x)z lenmetodą niestandardową , która robi zupełnie inne rzeczy.
Krótko mówiąc, masz zestaw bardzo typowych funkcji, które mogą implementować klasy, a do których można uzyskać dostęp za pośrednictwem operatora, poprzez specjalną funkcję (która zwykle robi więcej niż implementacja, jak zrobiłby to operator), podczas konstruowania obiektu i wszystkie z nich mają wspólne cechy. Cała reszta to metoda. I lenjest pewnym wyjątkiem od tej reguły.
len()lubreversed()stosuje się do wielu typów obiektów, ale metoda takaappend()ma zastosowanie tylko do sekwencji itp.