Koks yra jūsų tikslas?

Koks yra „ self žodis „python“? Suprantu, kad tai reiškia konkretų objektą, sukurtą iš šios klasės, tačiau negaliu suprasti, kodėl jis turėtų būti aiškiai pridėtas prie kiekvienos funkcijos kaip parametro. Norėdami iliustruoti, Ruby aš galiu tai padaryti:

25 апр. rinkinys richzilla 25 bal . 2010-04-25 23:22 '10, 23:22 pm 2010-04-25 23:22
@ 20 atsakymų

Priežastis, kodėl turite naudoti self. , yra tai, kad „Python“ nenaudoja @ sintaksės, kad galėtų nurodyti egzempliorių atributus. „Python“ nusprendė atlikti tokius metodus, kad atvejis, kuriam šis metodas priklauso, būtų automatiškai perduodamas, bet automatiškai nepriimamas: pirmasis metodo parametras yra metodas vadinamas pavyzdžiu. Dėl to metodai yra visiškai tokie patys, kaip ir funkcijos, ir paliekamas tikrasis vardas, kuris bus naudojamas prieš jus (nors self tai yra konvencija, o žmonės dažniausiai įsijungs į jus, kai naudojate kažką kitą). kitą objektą.

„Python“ galėjo ką nors padaryti, kad atskirtų normalius pavadinimus nuo atributų - specialios sintaksės, pvz., „Ruby“, arba reikalaujant deklaracijų, pvz., „C ++“ ir „Java“, arba galbūt kažką kitokio, bet ne. „Python“ yra apie tai, kad dalykai būtų aiškūs, kad tai būtų akivaizdu, ir nors ji to nepadaro, tai, pavyzdžiui, atributai. Todėl, norėdami priskirti atributą egzemplioriui, turite žinoti, kurį atvejį norite priskirti, ir kodėl jam reikia self. .

605
25 апр. Atsakyti Thomas Wouters 25 Bal 2010-04-25 23:25 '10, 23:25, 2010-04-25 23:25

Paimkite paprastą vektoriaus klasę:

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

Mes norime turėti metodą, kuris apskaičiuotų ilgį. Kas atrodytų, jei norėtume ją apibrėžti klasėje?

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

Ką jis turėtų atrodyti, kai turime jį apibrėžti kaip pasaulinį metodą / funkciją?

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

Taigi visa struktūra lieka tokia pati. Kaip jį naudoti? Jei tam tikru momentu darome prielaidą, kad nerašę length metodo mūsų Vector klasei, galėtume tai padaryti:

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

Tai veikia, nes pirmasis parametras, length_global gali būti pakartotinai naudojamas kaip self parametras length_new . Tai būtų neįmanoma be aiškios self .


Kitas būdas suprasti, kad reikia aiškaus self yra pamatyti, kur Python prideda tam tikrą sintaksinį cukrų. Atminkite, kad iš esmės skambučio tipas

 v_instance.length() 

viduje konvertuojami į

 Vector.length(v_instance) 

lengva pamatyti, kur self . Iš tiesų, Python'e nenurodote egzempliorių metodų; tai, ką rašote, yra klasės metodai, kurie turėtų būti pavyzdys kaip pirmasis parametras. Taigi reikia aiškiai nurodyti egzemplioriaus parametrą.

387
28 апр. Atsakymas pateikiamas Debilskio 28 d. 2010-04-28 03:03 '10, 3:03, 2010-04-28 03:03

Tarkime, jūs turite klasės ClassA , kuriame yra methodA apibrėžtas kaip:

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

ir ObjectA yra šios klasės pavyzdys.

Dabar, kai ObjectA.methodA(arg1, arg2) yra vadinamas, python jį viduje konvertuoja jums:

 ClassA.methodA(ObjectA, arg1, arg2) 

Kintamasis self reiškia patį objektą.

295
26 янв. atsakymą pateikė sausio 26 d. Arjun Sreedharan . 2014-01-26 20:31 '14, 20:31, 2014-01-26 20:31

Kai sukuriami objektai, pats objektas perduodamas savarankiškai.

2019

159
28 июня '15 в 8:47 2015-06-28 08:47 atsakymas pateikiamas sw123456 birželio 28 d. 15, 8:47 2015-06-28 08:47

Man patinka šis pavyzdys:

 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: [] 
65
26 апр. atsakymas įteiktas gandai 26 balandis. 2010-04-26 19:02 '10, 19:02, 2010-04-26 19:02

Su kodu pažymėsiu, kad ji nenaudoja klasių :

 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' 

Klasės yra tik būdas išvengti šios būsenos būklės perleidimo visą laiką (ir kiti gražūs dalykai, pvz., Inicijavimas, klasės sudėtis, retai reikalingi metaklasai ir parama individualiems metodams, skirtiems iš naujo apibrėžti operatorius).

Dabar parodyti aukščiau pateiktą kodą naudodami python klasės įmontuotą mašiną, kad parodytumėte, kaip jis iš esmės yra tas pats.

 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 ) 

[perkelti mano atsakymą iš uždarojo uždarojo klausimo]

33
22 июня '11 в 3:27 2011-06-22 03:27 atsakymas pateikiamas ninjagecko birželio 22 d. 11 val. 03:27 2011-06-22 03:27

Tai, kaip ir visos kitos minėtos priežastys, palengvina prieigą prie atsisakytų metodų; Galite skambinti Class.some_method(inst) .

Pavyzdys, kur tai yra naudinga:

 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" 
17
25 апр. Atsakymas pateikiamas Ponkadoodle 25 balandžio. 2010-04-25 23:31 '10, 11:31 val. 2010-04-25 23:31

Šie Python dokumentacijos ištraukos apie save :

Kaip ir Moduloje-3, nėra jokių santrumpų, kuriomis būtų galima remtis objektų nariais iš jo metodų [Pythone]: metodo funkcija deklaruojama aiškiu pirmuoju argumentu, vaizduojančiu netiesioginio skambučio teikiamą objektą.

Dažnai pirmasis argumentas dėl metodo vadinamas savimi. Tai nieko daugiau, kaip konvencija: pavadinimas „I“ neturi jokios ypatingos Python reikšmės. Tačiau atkreipkite dėmesį, kad nepaisydami konvencijos, jūsų kodas gali būti mažiau skaitomas kitiems „Python“ programuotojams, taip pat yra įmanoma, kad gali būti parašyta klasės naršyklės programa, kuri remiasi tokiu susitarimu.

Norėdami gauti daugiau informacijos, žr. „ Python“ dokumentacijos klasės pamoką .

16
25 апр. Atsakymą pateikė Matthew Rankin 25 Bal. 2010-04-25 23:29 '10, 11:29, 2010-04-25 23:29

Jo naudojimas yra panašus į this naudojimą „Java“, t.y. nurodyti dabartinį objektą.

11
30 авг. Gaurav Nishant atsakymas rugpjūčio 30 d. 2012-08-30 19:37 '12, 07:37 pm 2012-08-30 19:37

„Python“ nėra kalba, sukurta objekto programavimui, skirtingai nei „Java“ ar „C ++“.

Python skambindami statiniu metodu, paprasčiausiai parašykite šį metodą reguliariais argumentais.

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

Tačiau objekto metodas, kuriam reikalingas kintamasis, kuris šiuo atveju yra „Gyvūnai“, turi būti pats argumentas.

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

Savęs metodas taip pat naudojamas kintamojo lauko žymėjimui klasės viduje.

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

Šiuo atveju savarankiškai kalbama apie viso klasės kintamąjį „animalName“. ATMINKITE: Jei metode yra kintamasis, neveiksiu. Šis kintamasis tiesiog egzistuoja tik tada, kai šis metodas veikia. Norėdami apibrėžti laukus (viso klasės kintamuosius), turite apibrėžti jų OUTSIDE klasės metodus.

Jei nesuprantate žodžio apie tai, ką sakau, tada „Google“ „Objektinis programavimas“. Kai tai suprasite, jums net nereikės užduoti šio klausimo :).

11
25 мая '15 в 19:04 2015-05-25 19:04 atsakymą pateikė ytpillai gegužės 25 d., 15 val. 19:04 2015-05-25 19:04

Jo ten sekti Python zen, „aiškiau, nei numanomas“. Tai tikrai nuoroda į jūsų klasės objektą. Pavyzdžiui, „Java“ ir „PHP“ tai vadinama.

Jei „ user_type_name yra jūsų modelio laukas, galite gauti prieigą prie „ self.user_type_name .

7
16 авг. atsakymas pateikiamas dan-klasson 16 rug . 2013-08-16 20:23 '13, 20:23, 2013-08-16 20:23

self yra objekto nuoroda į patį objektą, todėl jie yra tie patys. Python metodai nėra vadinami paties objekto kontekste. „Python“ self gali būti naudojamas pritaikyti pasirinktinius objektų modelius ar ką nors kita.

4
25 апр. Atsakymą pateikė Ming-Tang balandžio 25 d 2010-04-25 23:26 '10, 11:26 PM 2010-04-25 23:26

Aš nustebęs, kad niekas nekėlė Lua. „Lua“ taip pat naudoja kintamąjį „savarankiškai“, bet galite jį praleisti, bet naudoti. C ++ daro tą patį su „this“. Aš nematau jokios priežasties skelbti „mane“ kiekvienoje funkcijoje, bet jūs vis tiek galite ją naudoti kaip ir lua ir C ++. Kalbai, kuri didžiuojasi tuo, kad yra trumpas, tai keista, kad jums reikia pasakyti apie save.

3
12 янв. atsakymą pateikė user441521 12 sausis 2016-01-12 21:10 '16 at 9:10 pm 2016-01-12 21:10

Taip yra todėl, kad „python“ yra sukurta, alternatyvos greičiausiai neveiks. Python yra skirtas apibrėžti metodus ar funkcijas kontekste, kuriame netiesioginis (a-la Java / C ++) arba aiškus @ (a-la ruby) neveiks. Pavyzdžiui, naudokite aiškų požiūrį su „python“ konvencijomis:

 def fubar(x): self.x = x class C: frob = fubar 

Dabar fubar funkcija neveiks, nes fubar , kad self yra pasaulinis kintamasis (taip pat ir frob ). Alternatyva būtų atlikti metodą su pakeista pasauline sritimi (kur self yra objektas).

Netiesioginis požiūris bus

 def fubar(x) myX = x class C: frob = fubar 

Tai reikštų, kad myX būtų interpretuojamas kaip vietinis kintamasis fubar (ir frob ). Alternatyva čia būtų atlikti metodus su pakeista vietine zona, kuri išlieka tarp skambučių, tačiau tai pašalins vietinio metodo kintamųjų galimybę.

Tačiau dabartinė situacija veikia gerai:

  def fubar(self, x) self.x = x class C: frob = fubar 

čia, kai jis vadinamas frob metodu, jis gaus objektą, kuriuo jis vadinamas per self parametrą, ir fubar vis dar gali būti vadinamas objektu kaip parametru ir veikia taip pat (tai yra tas pats, kaip C.frob manau).

2
27 авг. atsakymas pateikiamas skyking 27 rug . 2015-08-27 10:31 '15 , 10:31 am 2015-08-27 10:31

Visų pirma, aš esu bendras pavadinimas, galite įdėti kažką kitą (kad būtų nuoseklus).

Jis nurodo patį objektą, todėl, kai jį naudojate, jūs deklaruojate, kad .name ir .age yra studentų objektų (pastabų, o ne studentų klasės) savybės, kurias ketinate sukurti.

 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 

Kodas čia

2
12 янв. Atsakymą pateikė harrypotter0 12 sausis 2018-01-12 07:45 '18, 07:45 am 2018-01-12 07:45

Naudojant argumentą, sąlyginai vadinamą „ self , tai nėra taip sunku suprasti, nes tai būtina? Arba kodėl tai tiesiogiai paminėti? Tai, manau, yra didelis klausimas daugeliui vartotojų, kurie ieško šio klausimo, arba jei ne , jie tikrai turės tą patį klausimą, kaip ir ateityje, mokydamas „python“.

1: Savitarnos naudojimas

Atminkite, kad tai nėra raktinis žodis.

Pirmasis kiekvieno klasės metodo argumentas, įskaitant init, visada yra nuoroda į dabartinį klasės egzempliorių. Pagal susitarimą šis argumentas visada vadinamas savimi. In init metode nurodomas naujai sukurtas objektas; kituose klasės metoduose tai reiškia atvejį, kai metodas buvo vadinamas. Pvz., Žemiau pateiktas kodas yra toks pat, kaip aukščiau nurodytas kodas.

2: Kodėl mes jį turime ir kodėl negalime to atmesti kaip argumentą, pvz., „Java“, ir vietoj to naudoti raktinį žodį

Kitas dalykas, kurį norėčiau pridėti, yra neprivalomas self argumentas, leidžiantis man paskelbti statinius metodus klasės viduje be rašymo.

Kodo pavyzdžiai:

 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 : veikia tik Python 3.x.

Ankstesnėse versijose privalote aiškiai pridėti „ @staticmethod dekoratorių, kitaip reikalingas self argumentas.

1
01 авг. Atsakymas duotas Bugs Buggy 01 rug. 2018-08-01 13:53 '18 at 13:53 2018-08-01 13:53

Pažvelkite į šį pavyzdį, kuris aiškiai paaiškina self tikslą 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 naudojamasi / reikalingas norint atskirti atvejus.

1
15 нояб. atsakymas pateikiamas kmario23 lapkričio 15 d. 2014-11-15 10:54 '14, 10:54 2014-11-15 10:54

__init__ metodu savęs reiškia naujai sukurtą objektą; kituose klasės metoduose tai reiškia atvejį, kai metodas buvo vadinamas.

aš, kaip vardas, tik susitarimas , vadiname tai, ko norite! tačiau, pavyzdžiui, jei norite ištrinti objektą, turite naudoti tą patį pavadinimą: __del__(var) , kur var naudojamas __init__(var,[...])

Taip pat turėtumėte žiūrėti į cls kad padidintumėte vaizdą . Šis pranešimas gali būti naudingas.

1
26 янв. Atsakymą pateikė TheEnglishMe 26 sausis 2014-01-26 21:11 '14, 21:11 2014-01-26 21:11

„savęs“ naudojamas naujai sukurtam objektui nurodyti.

pavyzdžiui, jei deklaruojate metodą numatytąją klasę, jis automatiškai užima pirmąjį argumentą.

Pagal susitarimą, tai vadiname „man“ python.it tik stipriu susitarimu. Galite jį pavadinti kitu vardu.

Jei jums reikia metodo, kuriam nereikia prieigos prie savęs, naudokite statinį metodą:

 class TestClass(): @staticmethod def staticMethod(other_arg): print "This is a static method" def instanceMethod(self,other_arg): #This is instance method print "self is instance" ##If you want access to the class, but not to the instance, use classmethod: @classmethod def my_class_method(cls, other_arg): print "this is a class method" 
0
08 авг. atsakymą pateikė Projesh Bhoumik 08 rug . 2018-08-08 14:19 '18, 14:19 pm 2018-08-08 14:19

Tai yra aiški nuoroda į klasės egzemplioriaus objektą.

-3
25 апр. „SilentGhost“ atsakymas 25 Bal. 2010-04-25 23:24 '10, 23:24, 2010-04-25 23:24

Kiti klausimai apie etiketes „ arba „ Klauskite“