Jaki jest cel tego self
słowa w Pythonie? Rozumiem, że odnosi się do konkretnego obiektu utworzonego z tej klasy, ale nie rozumiem, dlaczego musi być jawnie dodawany do każdej funkcji jako parametr. Aby to zilustrować, w Ruby mogę to zrobić:
class myClass
def myFunc(name)
@name = name
end
end
Rozumiem to dość łatwo. Jednak w Pythonie muszę dołączyć self
:
class myClass:
def myFunc(self, name):
self.name = name
Czy ktoś może mi to powiedzieć? To nie jest coś, z czym się spotkałem (co prawda ograniczone) doświadczenie.
@name
bardziej intuicyjny niżself.name
? Ten ostatni, IMO, jest bardziej intuicyjny.@foo
iself.foo
są równie jednoznaczne, ponieważ nie musi zachodzić niejawne rozwiązanie problemu (np. w C ++ dostęp do elementów instancji można uzyskać „niejawnie” bez „jawnego” korzystania z przestrzeni nazw). Jedyną różnicą jest to, że Ruby wprowadza nowy semantyczny (@), podczas gdy Python nie. To, czy nowy semantyczny był wart tyle, ile uniknięto gadatliwości, jest czysto subiektywne. Chociaż należy zauważyć, że większość współczesnych języków decyduje się na wprowadzenie tutaj koncepcji (np. Php's $ this, JS's this).Odpowiedzi:
Powód, dla którego musisz użyć
self.
jest to, że Python nie używa@
składni do odwoływania się do atrybutów instancji. Python postanowił wykonać metody w taki sposób, że instancja, do której należy metoda, jest przekazywana automatycznie, ale nie odbierana automatycznie: pierwszym parametrem metod jest instancja, w której metoda jest wywoływana. To sprawia, że metody są całkowicie takie same, jak funkcje, i pozostawia do wyboru nazwę użytkownika (chociażself
jest to konwencja, a ludzie zwykle będą się na ciebie krzywo, gdy użyjesz czegoś innego).self
Nie jest wyjątkowy dla kodu, to tylko kolejny obiekt .Python mógł zrobić coś innego, aby odróżnić normalne nazwy od atrybutów - specjalną składnię, taką jak Ruby, lub wymagającą deklaracji takich jak C ++ i Java, a może coś jeszcze bardziej odmiennego - ale tak nie było. Python służy do tego, aby wyrażać rzeczy jasno, co jest oczywiste, i chociaż nie robi tego całkowicie wszędzie, robi to na przykład z atrybutami. Dlatego przypisanie do atrybutu instancji musi wiedzieć, do której instancji należy przypisać, i właśnie dlatego musi
self.
.źródło
cls
odnosi się do obiektu klasy, a nie obiektu instancjicls
iself
stosuje się ją konwencjonalnie na przykład w metodach. Gdybym chciał, mógłbym użyćself
metod klas icls
na przykład metod. Mógłbym również użyćbob
ifnord
jeśli mi się podobało.this
zamiastself
. Czyself
ma historię, której nie znam w starszych językach programowania?self
Pochodził z konwencji Modula-3, więcej informacji na temat tego wyboru można znaleźć w tej odpowiedzi . (Zastrzeżenie: jego kopalnia).self
kluczowe (Smalltalk, 1980) poprzedzathis
słowo kluczowe (z C ++). Zobacz: stackoverflow.com/questions/1079983/...Weźmy prostą klasę wektorów:
Chcemy mieć metodę obliczającą długość. Jak by to wyglądało, gdybyśmy chcieli zdefiniować to w klasie?
Jak powinien on wyglądać, gdy mieliśmy zdefiniować go jako globalną metodę / funkcję?
Cała struktura pozostaje taka sama. Jak mogę z tego skorzystać? Jeśli przez chwilę założymy, że nie napisaliśmy
length
metody dla naszejVector
klasy, moglibyśmy to zrobić:Działa to, ponieważ pierwszy parametr
length_global
, może być ponownie użyty jakoself
parametr wlength_new
. Nie byłoby to możliwe bez wyraźnegoself
.Innym sposobem zrozumienia potrzeby wyrażenia jawnego
self
jest sprawdzenie, gdzie Python dodaje cukier syntaktyczny. Kiedy pamiętasz, to w zasadzie połączenie takie jakzostał wewnętrznie przekształcony w
łatwo jest sprawdzić, gdzie
self
pasuje. W rzeczywistości nie piszesz metod instancji w Pythonie; piszesz metody klas, które muszą wziąć instancję jako pierwszy parametr. Dlatego musisz umieścić parametr instancji gdzieś wyraźnie.źródło
Vector.length_new = length_global
pokazuje.Załóżmy, że masz klasę,
ClassA
która zawiera metodęmethodA
zdefiniowaną jako:i
ObjectA
jest instancją tej klasy.Teraz, gdy
ObjectA.methodA(arg1, arg2)
jest wywoływany, Python wewnętrznie konwertuje go dla Ciebie jako:self
Zmienna odnosi się do samego obiektu.źródło
Podczas tworzenia instancji obiektów sam obiekt jest przekazywany do parametru własnego.
Z tego powodu dane obiektu są powiązane z obiektem. Poniżej znajduje się przykład wizualizacji wyglądu danych każdego obiektu. Zauważ, jak „jaźń” jest zastępowana nazwą obiektu. Nie twierdzę, że poniższy przykładowy diagram jest całkowicie dokładny, ale mam nadzieję, że służy celowi wizualizacji użycia jaźni.
Obiekt jest przekazywany do parametru własnego, dzięki czemu obiekt może przechowywać własne dane.
Chociaż może to nie być w pełni dokładne, pomyśl o procesie tworzenia instancji obiektu w ten sposób: Kiedy obiekt jest tworzony, wykorzystuje klasę jako szablon dla własnych danych i metod. Bez przekazania własnej nazwy do parametru własnego atrybuty i metody w klasie pozostałyby jako ogólny szablon i nie byłyby przywoływane (należały) do obiektu. Zatem przekazanie nazwy obiektu do parametru własnego oznacza, że jeśli utworzonych zostanie 100 obiektów z jednej klasy, wszystkie one mogą śledzić własne dane i metody.
Zobacz ilustrację poniżej:
źródło
Podoba mi się ten przykład:
źródło
self
ale także od typu zmiennej. Spróbuj zrobić pierwszy przykład z prostą liczbą całkowitą zamiast listy. Wynik byłby zupełnie inny.a.foo
w pierwszym przykładzie, a nieA.foo
? Najwyraźniejfoo
należy do klasy ...a
ib
to zarówno etykiety (lub wskaźniki) dlaA()
(klasy).a.foo
odwołuje się doA().foo
metody klasy. W drugim przykładzie, choća
stanie się odniesienia do przykładu zA()
, tak samob
. Teraz, gdy są instancjami zamiast samego obiektu klasy, self pozwalafoo
metodzie działać na instancjach.Pokażę za pomocą kodu, który nie korzysta z klas :
Klasy są tylko sposobem na uniknięcie ciągłego przechodzenia w tę „stanową” rzecz (i inne fajne rzeczy, takie jak inicjowanie, składanie klas, rzadko potrzebne metaklasy i wspieranie niestandardowych metod zastępowania operatorów).
Teraz pokażmy powyższy kod za pomocą wbudowanego mechanizmu klasy python, aby pokazać, jak to właściwie jest to samo.
[migrowałem moją odpowiedź z duplikatu pytania zamkniętego]
źródło
Poniższe fragmenty pochodzą z dokumentacji Pythona na temat siebie :
Aby uzyskać więcej informacji, zobacz samouczek dokumentacji klas Python .
źródło
Jak również wszystkie inne wymienione już powody, umożliwia łatwiejszy dostęp do zastąpionych metod; możesz zadzwonić
Class.some_method(inst)
.Przykład przydatności:
źródło
Jego użycie jest podobne do użycia
this
słowa kluczowego w Javie, tj. Do odniesienia do bieżącego obiektu.źródło
Python nie jest językiem zbudowanym dla programowania obiektowego w przeciwieństwie do Java lub C ++.
Podczas wywoływania metody statycznej w Pythonie wystarczy napisać metodę z regularnymi argumentami.
Jednak metoda obiektowa, która wymaga utworzenia zmiennej, jaką jest zwierzę, w tym przypadku wymaga argumentu własnego
Metoda własna jest również używana w odniesieniu do pola zmiennego w klasie.
W tym przypadku self odnosi się do zmiennej animalName całej klasy. PAMIĘTAJ: Jeśli masz zmienną w metodzie, self nie będzie działać. Ta zmienna istnieje po prostu tylko podczas działania tej metody. Aby zdefiniować pola (zmienne całej klasy), musisz zdefiniować je POZA metodami klasowymi.
Jeśli nie rozumiesz ani jednego słowa tego, co mówię, to Google „Programowanie obiektowe”. Kiedy to zrozumiesz, nie będziesz musiał nawet zadawać tego pytania :).
źródło
staticMethod()
iobjectMethod(self)
. Chciałbym dodać, że aby wywołać pierwszy, powiedziałbyśAnimal.staticMethod()
, podczas gdyobjectMethod()
potrzebuje instancji:a = Animal(); a.objectMethod()
def getAnimalName
aby nie blokować ciągu, który próbujesz zwrócić, iself
odnosi się do instancji klasy, a nie do dowolnego pola w niej.Ma podążać za zenem Pythona „wyraźne jest lepsze niż niejawne”. To rzeczywiście odniesienie do twojego obiektu klasy. Na przykład w Javie i PHP nazywa się to
this
.Jeśli
user_type_name
w twoim modelu jest pole, masz do niego dostępself.user_type_name
.źródło
Przede wszystkim „ja” to konwencjonalne imię, w którym można umieścić wszystko inne (spójne).
Odnosi się do samego obiektu, więc kiedy go używasz, deklarujesz, że .name i .age są właściwościami obiektów Student (uwaga, nie klasy Student), które zamierzasz utworzyć.
Kod jest tutaj
źródło
self
jest odwołaniem do obiektu do samego obiektu, dlatego są takie same. Metody w języku Python nie są wywoływane w kontekście samego obiektu.self
w Pythonie może być używany do obsługi niestandardowych modeli obiektów lub czegoś takiego.źródło
Zastosowanie argumentu, zwanego konwencjonalnie
self
nie jest tak trudne do zrozumienia, jak to jest konieczne? Lub dlaczego wprost to wymienia? To, jak sądzę, jest większe pytanie dla większości użytkowników, którzy szukają tego pytania, a jeśli nie, to na pewno będą mieli to samo pytanie, gdy przejdą do następnego etapu nauki pytona. Polecam im przeczytanie tych kilku blogów:1: Korzystanie z wyjaśnienia
Pamiętaj, że to nie jest słowo kluczowe.
2: Dlaczego mamy to w ten sposób i dlaczego nie możemy go wyeliminować jako argumentu, takiego jak Java, i zamiast tego mieć słowo kluczowe
Chciałbym również dodać, że opcjonalny
self
argument pozwala mi deklarować metody statyczne wewnątrz klasy, nie piszącself
.Przykłady kodu:
PS : Działa to tylko w Pythonie 3.x.
W poprzednich wersjach musisz jawnie dodać
@staticmethod
dekorator, w przeciwnym razieself
argument jest obowiązkowy.źródło
Dziwię się, że nikt nie wychował Lui. Lua używa również zmiennej „self”, jednak można ją pominąć, ale nadal jest używana. C ++ robi to samo z „tym”. Nie widzę żadnego powodu, by zadeklarować „jaźń” w każdej funkcji, ale nadal powinieneś być w stanie używać jej tak, jak możesz to zrobić w przypadku Lua i C ++. W przypadku języka, który szczyci się swoją krótkością, to dziwne, że wymaga zadeklarowania zmiennej własnej.
źródło
Spójrz na następujący przykład, który jasno wyjaśnia cel
self
self
jest używany / potrzebny do rozróżnienia między instancjami.Źródło: własna zmienna w Pythonie wyjaśniona - Pythontips
źródło
Jest tak, ponieważ sposób, w jaki został zaprojektowany Python, alternatywy raczej by nie działały. Python został zaprojektowany tak, aby umożliwić definiowanie metod lub funkcji w kontekście, w którym nie działałyby ani ukryte
this
(a-la Java / C ++) ani jawne@
(a-la ruby). Weźmy przykład z jawnym podejściem z konwencjami Pythona:Teraz
fubar
funkcja nie działałaby, ponieważ zakładałaby, żeself
jest to zmienna globalna (ifrob
również). Alternatywą byłoby wykonanie metody z zastąpionym zakresem globalnym (gdzieself
jest obiekt).Podejście niejawne byłoby
Oznaczałoby to, że
myX
byłby interpretowany jako zmienna lokalna wfubar
(ifrob
również w). Alternatywą byłoby tutaj wykonanie metod z zastąpionym zakresem lokalnym, który jest zachowywany między wywołaniami, ale wyeliminowałoby to możliwość lokalnych zmiennych metody.Jednak obecna sytuacja działa dobrze:
tutaj, gdy zostanie wywołany jako metoda
frob
, otrzyma obiekt, do którego jest wywoływany za pomocąself
parametru, ifubar
nadal może być wywoływany z obiektem jako parametrem i działa tak samo ( jest tak samo jakC.frob
myślę).źródło
W
__init__
metodzie self odnosi się do nowo utworzonego obiektu; w innych metodach klasowych odnosi się do instancji, której metoda została wywołana.jaźń, jak sama nazwa, to tylko konwencja , nazywaj ją jak chcesz! ale podczas korzystania z niego, na przykład do usuwania obiektu, musisz użyć tej samej nazwy:,
__del__(var)
gdzievar
został użyty w pliku__init__(var,[...])
Powinieneś też rzucić okiem
cls
, aby uzyskać większy obraz . Ten post może być pomocny.źródło
self działa jak bieżąca nazwa obiektu lub instancja klasy.
źródło
self
jest nieuniknione.Było po prostu kwestia powinna
self
być bezpośrednia lub pośrednia.Guido van Rossum
rozwiązałem to pytanie, mówiąc, żeself
musi zostać .Więc gdzie
self
mieszkasz?Gdybyśmy tylko trzymali się programowania funkcjonalnego, nie potrzebowalibyśmy
self
. Po wejściu do OOP Python znajdujemyself
tam.Oto typowy przypadek użycia
class C
tej metodym1
Ten program wyświetli:
self
Zawiera więc adres pamięci wystąpienia klasy. Celem ofself
byłoby trzymać odniesienia dla metody instancji i dla nas, aby mieć wyraźny dostęp do tego odniesienia.Uwaga: istnieją trzy różne typy metod klasowych:
źródło
z dokumentów ,
poprzedni powiązany fragment kodu,
x = MyClass()
źródło
jest to wyraźne odniesienie do obiektu instancji klasy.
źródło