Jaki jest cel słowa „ja”?

1130

Jaki jest cel tego selfsł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.

Richzilla
źródło
111
Interesujący może być ten esej „Dlaczego jawne ja musi zostać” Guido van Rossuma: neopythonic.blogspot.com/2008/10/...
unutbu
14
Zobacz także „Dlaczego„ ja ”musi być jawnie użyte w definicjach metod i wywołaniach”: docs.python.org/faq/…
unutbu
37
„Które rozumiem dość łatwo” --- Całkiem subiektywne, nie sądzisz? Co sprawia, że ​​jest @namebardziej intuicyjny niż self.name? Ten ostatni, IMO, jest bardziej intuicyjny.
Święty Mikołaj
14
To kluczowa różnica między funkcją a metodą klasową. Funkcja jest swobodna, nieobciążona. Metoda klasy (instancji) musi być świadoma swojej właściwości nadrzędnej (i właściwości nadrzędnej), dlatego należy przekazać metodzie odwołanie do klasy nadrzędnej (jako siebie ). To tylko jedna mniej domyślna zasada, którą musisz zinternalizować, zanim zrozumiesz OOP. Inne języki wybierają cukier składniowy zamiast semantycznej prostoty, python nie jest innymi językami.
Evan Plaice,
9
Nie sądzę, że „wyraźne jest lepsze niż niejawne” naprawdę dobrze wyjaśnia ten wybór projektu. @fooi self.foosą 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).
Jing

Odpowiedzi:

710

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ż selfjest to konwencja, a ludzie zwykle będą się na ciebie krzywo, gdy użyjesz czegoś innego). selfNie 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..

Thomas Wouters
źródło
23
@Georg: clsodnosi się do obiektu klasy, a nie obiektu instancji
SilentGhost
17
@SilentGhost: W rzeczywistości nazwa pierwszego parametru jest taka, jaka ma być. W przypadku metod klasowych stosuje się konwencję clsi selfstosuje się ją konwencjonalnie na przykład w metodach. Gdybym chciał, mógłbym użyć selfmetod klas i clsna przykład metod. Mógłbym również użyć bobi fnordjeśli mi się podobało.
SingleNegationElimination
67
Uważam za interesujące, że społeczność nie wybrała thiszamiast self. Czy selfma historię, której nie znam w starszych językach programowania?
Jules GM
24
@Julius selfPochodził z konwencji Modula-3, więcej informacji na temat tego wyboru można znaleźć w tej odpowiedzi . (Zastrzeżenie: jego kopalnia).
Bakuriu,
9
@Julius Słowo selfkluczowe (Smalltalk, 1980) poprzedza thissłowo kluczowe (z C ++). Zobacz: stackoverflow.com/questions/1079983/...
Wes Turner,
425

Weźmy prostą klasę wektorów:

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

Chcemy mieć metodę obliczającą długość. Jak by to wyglądało, gdybyśmy chcieli zdefiniować to w klasie?

    def length(self):
        return math.sqrt(self.x ** 2 + self.y ** 2)

Jak powinien on wyglądać, gdy mieliśmy zdefiniować go jako globalną metodę / funkcję?

def length_global(vector):
    return math.sqrt(vector.x ** 2 + vector.y ** 2)

Cała struktura pozostaje taka sama. Jak mogę z tego skorzystać? Jeśli przez chwilę założymy, że nie napisaliśmy lengthmetody dla naszej Vectorklasy, moglibyśmy to zrobić:

Vector.length_new = length_global
v = Vector(3, 4)
print(v.length_new()) # 5.0

Działa to, ponieważ pierwszy parametr length_global, może być ponownie użyty jako selfparametr w length_new. Nie byłoby to możliwe bez wyraźnego self.


Innym sposobem zrozumienia potrzeby wyrażenia jawnego selfjest sprawdzenie, gdzie Python dodaje cukier syntaktyczny. Kiedy pamiętasz, to w zasadzie połączenie takie jak

v_instance.length()

został wewnętrznie przekształcony w

Vector.length(v_instance)

łatwo jest sprawdzić, gdzie selfpasuje. 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.

Debilski
źródło
4
Vector.length_new = length_global ... Właściwie zacząłem używać takiej składni w deklaracjach klas. Ilekroć chcę dziedziczyć tylko niektóre metody z innej klasy, po prostu jawnie kopiuję odwołanie do metod.
Jeeyoung Kim
2
czy można uczciwie powiedzieć, że „metoda instancji” Pythona to po prostu cukier składniowy statycznych metod globalnych (jak w Javie lub C ++) z obiektem instancji przekazanym w celu spakowania wielu atrybutów? --- cóż, jest to w połowie prawda, ponieważ w polimorfizmie ważniejszym celem „tego” (jak w java) lub „ja” jest zapewnienie poprawnej implementacji metod. Python ma to. więc wywołanie myobj.someMethod () jest równe TheClassOfMyObj.someMethod (myobj) w pythonie. zauważ, że „TheClassOfMyObj” jest automatycznie rozpoznawany przez python z „self”, w przeciwnym razie musiałbyś się tego dowiedzieć.
teddy teddy
3
Rzeczywiście, nie tylko metody instancji są tylko metodami klasowymi, ale metody są po prostu funkcjami, które są członkami klasy, jak Vector.length_new = length_globalpokazuje.
RussW,
1
„To działa, ponieważ pierwszy parametr length_global może być ponownie użyty jako parametr własny w length_new. Nie byłoby to możliwe bez wyraźnego self.” - działałoby tak samo. byłby ponownie użyty dla niejawnego ja ... drugi przykład jest kołowym rozumowaniem - musisz jawnie tam umieścić ja, ponieważ python potrzebuje jawnego ja.
Karoly Horvath,
1
@KarolyHorvath: Jasne, byłoby również możliwe, aby mieć język z modelem, w którym metody zdefiniowane wewnętrznie nie potrzebują jawnego ja, ale metody zdefiniowane zewnętrznie. Ale powiedziałbym, że istnieje pewna konsekwencja w wymaganiu wyraźnego „ja” w obu przypadkach, co czyni uzasadniony powód, aby robić to w ten sposób. Inne języki mogą wybierać różne podejścia.
Debilski
420

Załóżmy, że masz klasę, ClassAktóra zawiera metodę methodAzdefiniowaną jako:

def methodA(self, arg1, arg2):
    # do something

i ObjectAjest instancją tej klasy.

Teraz, gdy ObjectA.methodA(arg1, arg2)jest wywoływany, Python wewnętrznie konwertuje go dla Ciebie jako:

ClassA.methodA(ObjectA, arg1, arg2)

selfZmienna odnosi się do samego obiektu.

Arjun Sreedharan
źródło
94
Przeczytałem wszystkie inne odpowiedzi i w pewnym sensie zrozumiałem, przeczytałem tę, a potem wszystko miało sens.
Seth
3
To mnie przybiło!
Bernard „Beta Berlin” Parah
2
Dlaczego nie zatrzymać tych wnętrzności, tak jak Ruby?
Cees Timmerman
Ale w metodzie __init __ (self) akceptuje siebie, a nawet bez tworzenia obiektu, jak odnosi się do siebie?
saurav
Poważnie, jest to znacznie lepsze niż przykład Debilskiego, ponieważ nie jest zbyt skomplikowane i ludzie mogą nie znać wektorów.
NoName
215

Podczas tworzenia instancji obiektów sam obiekt jest przekazywany do parametru własnego.

wprowadź opis zdjęcia tutaj

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.

wprowadź opis zdjęcia tutaj

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:

wprowadź opis zdjęcia tutaj

sw123456
źródło
Hej, podczas uzyskiwania dostępu do atrybutów Boba, na przykład przez „bob.name ()”, faktycznie uzyskujesz dostęp do bob (). Self.name, że tak powiem z „ init ”, prawda?
udarH3,
3
Kiedy piszesz bob.name () w powyższym komentarzu, sugerujesz, że bob ma metodę o nazwie name () ze względu na to, że dodałeś nawiasy po nazwie. W tym przykładzie jednak nie ma takiej metody. „bob.name” (który nie ma nawiasu) bezpośrednio uzyskuje dostęp do atrybutu o nazwie name z metody init (konstruktor). Gdy wywoływana jest metoda speak bob, jest to metoda, która uzyskuje dostęp do atrybutu name i zwraca go w instrukcji print. Mam nadzieję że to pomoże.
sw123456,
3
Nie, otrzymujesz wartość self.name, która dla obiektu bob jest w rzeczywistości bob.name, ponieważ nazwa obiektu jest przekazywana do parametru własnego podczas jego tworzenia (tworzenia instancji). Znowu mam nadzieję, że to pomoże. Zachęcamy do głosowania za głównym postem, jeśli ma.
sw123456
2
Nazwa jest przypisywana do self.name w momencie tworzenia. Po utworzeniu obiektu wszystkie zmienne należące do obiektu to te, które mają przedrostek „self”. Pamiętaj, że self jest zastępowane nazwą obiektu, gdy jest tworzony z klasy.
sw123456
5
Oto jak tłumaczysz różne rzeczy! dobra robota :)
penta
80

Podoba mi się ten przykład:

class A: 
    foo = []
a, b = A(), A()
a.foo.append(5)
b.foo
ans: [5]

class A: 
    def __init__(self): 
        self.foo = []
a, b = A(), A()
a.foo.append(5)
b.foo
ans: []
Kame
źródło
18
więc vars bez siebie to po prostu statyczne varsy klasy, jak w java
teddy teddy
5
Teddy Teddy, nie masz całkowitej racji. Zachowanie (takie jak statyczne lub niestatyczne) zależy nie tylko od, selfale także od typu zmiennej. Spróbuj zrobić pierwszy przykład z prostą liczbą całkowitą zamiast listy. Wynik byłby zupełnie inny.
Konstantin
2
Właściwie moje pytanie brzmi: dlaczego wolno ci powiedzieć a.foow pierwszym przykładzie, a nie A.foo? Najwyraźniej foonależy do klasy ...
Radon Rosborough
W większości języków można wywoływać elementy statyczne z instancji obiektu. Dlaczego to jest zaskakujące?
Paarth
2
@RadonRosborough Ponieważ w pierwszym przykładzie, ai bto zarówno etykiety (lub wskaźniki) dla A()(klasy). a.fooodwołuje się do A().foometody klasy. W drugim przykładzie, choć astanie się odniesienia do przykładu z A(), tak samo b. Teraz, gdy są instancjami zamiast samego obiektu klasy, self pozwala foometodzie działać na instancjach.
LegendaryDude
40

Pokażę za pomocą kodu, który nie korzysta z klas :

def state_init(state):
    state['field'] = 'init'

def state_add(state, x):
    state['field'] += x

def state_mult(state, x):
    state['field'] *= x

def state_getField(state):
    return state['field']

myself = {}
state_init(myself)
state_add(myself, 'added')
state_mult(myself, 2)

print( state_getField(myself) )
#--> 'initaddedinitadded'

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.

class State(object):
    def __init__(self):
        self.field = 'init'
    def add(self, x):
        self.field += x
    def mult(self, x):
        self.field *= x

s = State()
s.add('added')    # self is implicitly passed in
s.mult(2)         # self is implicitly passed in
print( s.field )

[migrowałem moją odpowiedź z duplikatu pytania zamkniętego]

ninjagecko
źródło
1
Chciałbym, aby Python pokrył cukrem obsługi, tak jak Ruby.
Cees Timmerman
20

Poniższe fragmenty pochodzą z dokumentacji Pythona na temat siebie :

Podobnie jak w Modula-3, nie ma skrótów [w Pythonie] do odwoływania się do elementów obiektu z jego metod: funkcja metody jest zadeklarowana z wyraźnym pierwszym argumentem reprezentującym obiekt, który jest niejawnie wywołany przez wywołanie.

Często pierwszy argument metody nazywa się self. To nic innego jak konwencja: nazwa self nie ma absolutnie żadnego specjalnego znaczenia dla Pythona. Zauważ jednak, że nieprzestrzeganie konwencji może spowodować, że kod będzie mniej czytelny dla innych programistów Pythona, i możliwe jest również napisanie programu do przeglądania klas, który opiera się na takiej konwencji.

Aby uzyskać więcej informacji, zobacz samouczek dokumentacji klas Python .

Matthew Rankin
źródło
20

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:

class C1(object):
    def __init__(self):
         print "C1 init"

class C2(C1):
    def __init__(self): #overrides C1.__init__
        print "C2 init"
        C1.__init__(self) #but we still want C1 to init the class too
>>> C2()
"C2 init"
"C1 init"
Ponkadoodle
źródło
17

Jego użycie jest podobne do użycia thissłowa kluczowego w Javie, tj. Do odniesienia do bieżącego obiektu.

Gaurav Nishant
źródło
2
klasa myClass: def myFunc (this, name): this.name = name
LEMUEL ADANE
16

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.

class Animal():
    def staticMethod():
        print "This is a static method"

Jednak metoda obiektowa, która wymaga utworzenia zmiennej, jaką jest zwierzę, w tym przypadku wymaga argumentu własnego

class Animal():
    def objectMethod(self):
        print "This is an object method which needs an instance of a class"

Metoda własna jest również używana w odniesieniu do pola zmiennego w klasie.

class Animal():
    #animalName made in constructor
    def Animal(self):
        self.animalName = "";


    def getAnimalName(self):
        return self.animalName

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 :).

ytpillai
źródło
+1 z powodu rozróżnienia między staticMethod()i objectMethod(self). Chciałbym dodać, że aby wywołać pierwszy, powiedziałbyś Animal.staticMethod(), podczas gdy objectMethod()potrzebuje instancji:a = Animal(); a.objectMethod()
Laryx Decidua
To, co mówisz, nie jest w 100% prawdą. To tylko konwencja. Nadal możesz wywoływać metodę statyczną z utworzonego obiektu. Po prostu nie będziesz mógł używać członków klasy, ponieważ nie zadeklarowałeś siebie. Mogę nawet wywołać Animal.objectMethod (animalObj), aby wywołać niestatyczną. Zasadniczo oznacza to, że metoda statyczna jest tylko metodą, która nie używa zmiennych składowych. Nie powinno być potrzeby deklarowania siebie. Myślę, że to głupi wymóg językowy. Języki takie jak Lua i C ++ dają ci zmienne obj za kulisami.
user441521,
Zrobiłeś bezużyteczną deklarację łańcuchową animalName i zawiesiłeś metodę animalName.
Cees Timmerman
3
@ytpillai Nieistotne. Mylący i niepoprawny kod nie powinien być prezentowany jako odpowiedź.
Cees Timmerman
1
def getAnimalNameaby nie blokować ciągu, który próbujesz zwrócić, i selfodnosi się do instancji klasy, a nie do dowolnego pola w niej.
Cees Timmerman
10

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_namew twoim modelu jest pole, masz do niego dostęp self.user_type_name.

dan-klasson
źródło
10

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ć.

class Student:
    #called each time you create a new Student instance
    def __init__(self,name,age): #special method to initialize
        self.name=name
        self.age=age

    def __str__(self): #special method called for example when you use print
        return "Student %s is %s years old" %(self.name,self.age)

    def call(self, msg): #silly example for custom method
        return ("Hey, %s! "+msg) %self.name

#initializing two instances of the student class
bob=Student("Bob",20)
alice=Student("Alice",19)

#using them
print bob.name
print bob.age
print alice #this one only works if you define the __str__ method
print alice.call("Come here!") #notice you don't put a value for self

#you can modify attributes, like when alice ages
alice.age=20
print alice

Kod jest tutaj

Akash Kandpal
źródło
1
Twoja odpowiedź wydaje mi się najbardziej jasna. +1
Paweł
9

selfjest 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. selfw Pythonie może być używany do obsługi niestandardowych modeli obiektów lub czegoś takiego.

Ming-Tang
źródło
8

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.

Pierwszy argument każdej metody klasy, w tym init, jest zawsze odniesieniem do bieżącej instancji klasy. Zgodnie z konwencją ten argument zawsze nosi nazwę „ja”. W metodzie init self odnosi się do nowo utworzonego obiektu; w innych metodach klasowych odnosi się do instancji, której metoda została wywołana. Na przykład poniższy kod jest taki sam jak powyższy kod.

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 selfargument pozwala mi deklarować metody statyczne wewnątrz klasy, nie piszącself .

Przykłady kodu:

class MyClass():
    def staticMethod():
        print "This is a static method"

    def objectMethod(self):
        print "This is an object method which needs an instance of a class, and that is what self refers to"

PS : Działa to tylko w Pythonie 3.x.

W poprzednich wersjach musisz jawnie dodać @staticmethoddekorator, w przeciwnym razie selfargument jest obowiązkowy.

Błędy Buggy
źródło
7

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.

użytkownik441521
źródło
6

Spójrz na następujący przykład, który jasno wyjaśnia cel self

class Restaurant(object):  
    bankrupt = False

    def open_branch(self):
        if not self.bankrupt:
           print("branch opened")

#create instance1
>>> x = Restaurant()
>>> x.bankrupt
False

#create instance2
>>> y = Restaurant()
>>> y.bankrupt = True   
>>> y.bankrupt
True

>>> x.bankrupt
False  

self jest używany / potrzebny do rozróżnienia między instancjami.

Źródło: własna zmienna w Pythonie wyjaśniona - Pythontips

kmario23
źródło
Tak, myślę, że wiemy, dlaczego używa się ja, ale pytanie brzmi, dlaczego język sprawia, że ​​wyraźnie to deklarujesz. Wiele innych języków tego nie wymaga, a język, który szczyci się swoją krótkością, pomyślałbyś, że podadzą ci zmienną za kulisami, której możesz używać tak jak Lua lub C ++ (to).
user441521,
3
@ kmario23 Twoja odpowiedź pochodziła stąd: pythontips.com/2013/08/07/the-self-variable-in-python-expllained Przy wysyłaniu odpowiedzi zawsze należy podać oryginalnych autorów.
geekidharsh
@geekidharsh dzięki, dodałem notatkę!
kmario23
5

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:

def fubar(x):
    self.x = x

class C:
    frob = fubar

Teraz fubarfunkcja nie działałaby, ponieważ zakładałaby, że selfjest to zmienna globalna (i frobrównież). Alternatywą byłoby wykonanie metody z zastąpionym zakresem globalnym (gdzieself jest obiekt).

Podejście niejawne byłoby

def fubar(x)
    myX = x

class C:
    frob = fubar

Oznaczałoby to, że myXbyłby interpretowany jako zmienna lokalna w fubar(i frobró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:

 def fubar(self, x)
     self.x = x

 class C:
     frob = fubar

tutaj, gdy zostanie wywołany jako metoda frob, otrzyma obiekt, do którego jest wywoływany za pomocą selfparametru, i fubarnadal może być wywoływany z obiektem jako parametrem i działa tak samo ( jest tak samo jak C.frobmyślę).

Król nieba
źródło
3

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.

Oussama L.
źródło
3

self działa jak bieżąca nazwa obiektu lub instancja klasy.

# Self explanation.


 class classname(object):

    def __init__(self,name):

        self.name=name
        # Self is acting as a replacement of object name.
        #self.name=object1.name

   def display(self):
      print("Name of the person is :",self.name)
      print("object name:",object1.name)


 object1=classname("Bucky")
 object2=classname("ford")

 object1.display()
 object2.display()

###### Output 
Name of the person is : Bucky
object name: Bucky
Name of the person is : ford
object name: Bucky
same_nubia
źródło
1

self jest nieuniknione.

Było po prostu kwestia powinna selfbyć bezpośrednia lub pośrednia. Guido van Rossumrozwiązałem to pytanie, mówiąc, że selfmusi zostać .

Więc gdzie selfmieszkasz?

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 Ctej metodym1

class C:
    def m1(self, arg):
        print(self, ' inside')
        pass

ci =C()
print(ci, ' outside')
ci.m1(None)
print(hex(id(ci))) # hex memory address

Ten program wyświetli:

<__main__.C object at 0x000002B9D79C6CC0>  outside
<__main__.C object at 0x000002B9D79C6CC0>  inside
0x2b9d79c6cc0

selfZawiera więc adres pamięci wystąpienia klasy. Celem of selfbył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:

  • metody statyczne (czytaj: funkcje),
  • metody klasowe,
  • metody instancji (wspomniane).
prosti
źródło
0

z dokumentów ,

szczególną cechą metod jest to, że obiekt instancji jest przekazywany jako pierwszy argument funkcji. W naszym przykładzie połączenie x.f()jest dokładnie równoważne z MyClass.f(x). Zasadniczo wywołanie metody z listą n argumentów jest równoważne z wywołaniem odpowiedniej funkcji z listą argumentów, która jest tworzona przez wstawienie obiektu instancji metody przed pierwszym argumentem.

poprzedni powiązany fragment kodu,

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

x = MyClass()

nmxl
źródło
-2

jest to wyraźne odniesienie do obiektu instancji klasy.

SilentGhost
źródło
21
Nie sądzę, żeby to pomogło Richzilli zrozumieć przyczynę.
Georg Schölly,
1
@SilentGhost: przybiłeś go. Jestem pod wrażeniem. jeśli dobrze to rozumiem: czy tworzę obiekt jako instancję zdefiniowanej klasy, a parametr własny odnosi się do tego obiektu? Rozumiem, że ja odnosi się w sposób dorozumiany do samej klasy, ale byłoby wspaniale, gdybyś wyjaśnił nieco swoją odpowiedź.
dkrynicki