Wiem, że python ma len()
funkcję służącą do określania rozmiaru łańcucha, ale zastanawiałem się, dlaczego nie jest to metoda obiektu łańcucha.
Aktualizacja
Ok, zrozumiałem, że się wstydziłem. __len__()
jest właściwie metodą obiektu łańcuchowego. Po prostu dziwnie jest widzieć kod zorientowany obiektowo w Pythonie za pomocą funkcji len na obiektach łańcuchowych. Co więcej, dziwnie jest też patrzeć __len__
na nazwę zamiast po prostu len.
len
. Uważają, że łatwiej jest zmusić ludzi do wdrożenia.__len__
niż zmusić ludzi do wdrożenia.len()
. To to samo i wygląda na znacznie czystszego. Jeśli język ma mieć OOP__len__
, co na świecie ma senslen(..)
__iter__
lub tylko__getitem__
iiter(x)
będzie działał w obu kierunkach. Możesz utworzyć obiekt kontekstu użytecznego w bool za pomocą__bool__
lub__len__
ibool(x)
będzie działał w obie strony. I tak dalej. Myślę, że Armin wyjaśnia to dość dobrze w powiązanym poście - ale nawet gdyby nie zrobił, nazywanie Pytona głupkiem z powodu zewnętrznego wyjaśnienia faceta, który często publicznie kłóci się z głównymi deweloperami, nie byłoby w porządku…zip
jest funkcją najwyższego poziomu, a niezip_with
metodą. I tak dalej. To, że wszystko jest przedmiotem, nie oznacza, że bycie przedmiotem jest najważniejsze w każdej rzeczy.Odpowiedź Jima na to pytanie może pomóc; Kopiuję to tutaj. Cytując Guido van Rossum:
źródło
Istnieje
len
metoda:źródło
Python jest pragmatyczny język programowania, a przyczyny
len()
jest funkcją, a nie metodastr
,list
,dict
itd. Są pragmatyczne.len()
Wbudowanej funkcji zajmuje się bezpośrednio z wbudowanych typów: realizacja CPython odlen()
faktycznie zwraca wartośćob_size
pola wPyVarObject
struct C , który reprezentuje dowolny zmiennej wielkości wbudowanego obiektu w pamięci. Jest to o wiele szybsze niż wywoływanie metody - nie trzeba wyszukiwać atrybutów. Pierwsze liczbę elementów w kolekcji jest wspólna praca i musi pracować wydajnie dla takich podstawowych i zróżnicowanych typów jakstr
,list
,array.array
itd.Jednak w celu promowania spójności przy stosowaniu
len(o)
do typu zdefiniowanego przez użytkownika Python wywołujeo.__len__()
funkcję rezerwową.__len__
,__abs__
a wszystkie inne specjalne metody udokumentowane w Python Data Model ułatwiają tworzenie obiektów, które zachowują się jak wbudowane, umożliwiając ekspresyjne i wysoce spójne interfejsy API, które nazywamy „Pythonic”.Wdrażając specjalne metody, Twoje obiekty mogą obsługiwać iterację, przeciążać operatorów poprawki, zarządzać kontekstami w
with
blokach itp. Model danych można traktować jako sposób wykorzystania samego języka Python jako struktury, w której tworzone obiekty można bezproblemowo zintegrować.Drugim powodem, popartym cytatami z Guido van Rossum, takimi jak ten , jest to, że łatwiej jest czytać i pisać
len(s)
niżs.len()
.Notacja
len(s)
jest spójna z jednoargumentowymi operatorami z notacją przedrostkową, npabs(n)
.len()
jest używany znacznie częściej niżabs()
i zasługuje na równie łatwą pisanie.Przyczyna może być także historyczna: w języku ABC poprzedzającym Pythona (który miał duży wpływ na jego konstrukcję) istniał
#s
jednoznaczny operator, co oznaczałolen(s)
.źródło
źródło
Jest tu kilka świetnych odpowiedzi, więc zanim dam własne, chciałbym podkreślić kilka klejnotów (nie zamierzam używać ruby punka), które przeczytałem tutaj.
len
rzeczywistości jest obiektem. Z drugiej strony Ruby nie ma funkcji pierwszej klasy. Tak więclen
przedmiotem funkcja ma własne metody, które można sprawdzić, uruchamiającdir(len)
.Jeśli nie podoba ci się sposób, w jaki działa to we własnym kodzie, to jest trywialne, aby ponownie wdrożyć kontenery przy użyciu preferowanej metody (patrz przykład poniżej).
źródło
Możesz też powiedzieć
Korzystanie z Python 2.7.3.
źródło
len
funkcja była już wspomniana w poprzednich odpowiedziach. Jaki jest zatem sens tej „odpowiedzi”?Coś brakuje w pozostałych odpowiedziach tutaj:
len
funkcja sprawdza, czy__len__
metoda zwraca wartość nieujemnąint
. Fakt, żelen
jest funkcją, oznacza, że klasy nie mogą zastąpić tego zachowania, aby uniknąć sprawdzenia. Jako takilen(obj)
daje poziom bezpieczeństwa, któryobj.len()
nie może.Przykład:
Oczywiście możliwe jest „przesłonięcie”
len
funkcji przez ponowne przypisanie jej jako zmiennej globalnej, ale kod, który to robi, jest znacznie bardziej podejrzany niż kod, który przesłania metodę w klasie.źródło
Nie?
źródło