Programuję w wielu językach, takich jak Java, Ruby, Haskell i Python. Muszę przełączać się między wieloma językami dziennie z powodu różnych projektów, nad którymi pracuję. Problem polega na tym, że często zapominam pisać self
jako pierwszy parametr w definicjach funkcji w Pythonie tak samo, jak w przypadku wywoływania metod na tym samym obiekcie.
To powiedziawszy, jestem dość zaskoczony tym podejściem Pythona. Zasadniczo musimy pisać więcej, aby załatwić sprawę, w językach takich jak Java i Ruby rzeczy stają się proste dzięki automatycznemu odwoływaniu się do zmiennych w bieżącym obiekcie.
Moje pytanie brzmi: dlaczego jest to self
konieczne? Czy jest to wyłącznie wybór stylu, czy jest powód, dla którego Python nie pozwala ci pominąć self
sposobu, w jaki Java i C ++ pozwalają ci pominąć this
?
@staticmethod
przed deklaracją metody pomija błąd (tylko dla informacji, a także niezalecany)Odpowiedzi:
1) Dlaczego jest
self
wymagany jako wyraźny parametr w podpisach metod?Ponieważ metody są funkcjami i
foo.bar(baz)
są po prostu cukrem syntaktycznymbar(foo, baz)
. Klasy to tylko słowniki, w których niektóre wartości są funkcjami. (Konstruktory to również tylko funkcje, dlatego Python nie potrzebujenew
). Można powiedzieć, że Python wyraźnie mówi, że obiekty są zbudowane z prostszych komponentów. Jest to zgodne z filozofią „jawne jest lepsze niż niejawne”.Natomiast w Javie obiekty są naprawdę magiczne i nie można ich sprowadzić do prostszych elementów w języku. W Javie (przynajmniej do Java 8) funkcja jest zawsze metodą będącą własnością obiektu, a tej własności nie można zmienić z powodu statycznej natury języka. Dlatego nie ma dwuznaczności w
this
odniesieniu do tego, co się odnosi, więc sensowne jest, aby to domyślnie zdefiniować.JavaScript jest przykładem języka, który ma niejawny charakter,
this
taki jak Java, ale gdzie funkcje mogą istnieć niezależnie od obiektów takich jak Python. Prowadzi to do wielu nieporozumień dotyczących tego, cothis
odnosi się, gdy funkcje są przekazywane i wywoływane w różnych kontekstach. Wielu instynktownie uważa, żethis
musi odnosić się do pewnych wewnętrznych właściwości funkcji, podczas gdy jest ona w rzeczywistości określana wyłącznie przez sposób jej wywoływania. Wierzę, że posiadaniethis
tak wyraźnego parametru jak w Pythonie sprawiłoby, że byłoby to mniej skomplikowane.Kilka innych korzyści z jawnego
self
parametru:Dekoratory to tylko funkcje, które obejmują inne funkcje. Ponieważ metody są tylko funkcjami, dekoratorzy działają równie dobrze na metodach. Gdyby istniało jakieś ukryte ja, dekoratorzy nie pracowaliby transparentnie nad metodami.
Metody klas i metody statyczne nie przyjmują parametru instancji. Metody klas przyjmują klasę jako pierwszy argument (zwykle nazywany
cls
). Wyraźneself
lubcls
parametry znacznie wyjaśniają, co się dzieje i do czego masz dostęp w metodzie.2) Dlaczego zmienne instancji muszą zawsze być kwalifikowane za pomocą „
self.
?W Javie nie trzeba poprzedzać zmiennych członkowskich znakiem „
this.
”, ale w Pythonie „self.
” jest zawsze wymagane. Powodem jest to, że Python nie ma jawnej składni do deklarowania zmiennych, więc nie byłoby sposobu, aby stwierdzić, czyx = 7
należy zadeklarować nową zmienną lokalną lub przypisać do zmiennej członka. Określenieself.
rozwiązuje tę dwuznaczność.źródło
self.
, np. Java) jest zasadniczo niezgodne z regułami określania zakresu, a kiedy trzeba tam być jawnym, domniemanie dotyczące parametru nie ma już większego sensu.Istnieje dość prosty powód, dla którego AFAIK nie został tak naprawdę poruszony w duplikacie strony krzyżowej, ani tutaj: Python zaczął jako język proceduralny. Oparty był na ABC, również języku proceduralnym.
Orientacja obiektowa została dodana później, a kiedy została dodana, Guido van Rossum chciał dodać minimalną liczbę możliwych funkcji, aby zachować prostotę projektowania Pythona. Python ma już
dict
s i funkcje, więc po co dodawać do języka coś zupełnie nowego, skoro obiekt może być po prostudict
gniazdem, a klasa może po prostu byćdict
funkcją? Metodę można interpretować jako częściowo zastosowaną funkcję, która zamyka pojedynczy wyróżniony argument. I tak właśnie metody są implementowane w Pythonie: nie są. Są to tylko funkcje, które otrzymują dodatkowy wyróżniający się argument.źródło
Oto moje wnioski w oparciu o powyższe odpowiedzi i czytanie własnych Guido wędrówki na ten temat:
Wielki pomysł
Funkcje są ważnymi elementami składowymi Pythona (a raczej powinniśmy powiedzieć, że jedynymi), w rzeczywistości naśladujemy OOP za pomocą funkcji.
Biorąc pod uwagę, że klasa jest jedynie słownikiem funkcji, w związku z tym możemy dołączyć dowolną funkcję do dowolnej klasy w czasie wykonywania. Zasadniczo to z powodu potrzeby przerzucania funkcji w czasie wykonywania możemy robić rzeczy takie jak Monkey Patching . Tutaj
self
parametr wspierający parametryczny polimorfizm.źródło