Qual è lo scopo della parola 'sé'?


1130

Qual è lo scopo della selfparola in Python? Capisco che si riferisce all'oggetto specifico creato da quella classe, ma non riesco a capire perché debba essere esplicitamente aggiunto ad ogni funzione come parametro. Per illustrare, in Ruby posso fare questo:

class myClass
    def myFunc(name)
        @name = name
    end
end

Che capisco, abbastanza facilmente. Tuttavia in Python devo includere self:

class myClass:
    def myFunc(self, name):
        self.name = name

Qualcuno può parlarmi attraverso questo? Non è qualcosa che mi sono imbattuto nella mia (certamente limitata) esperienza.


111
Potresti trovare interessante questo saggio "Perché il sé esplicito deve rimanere" di Guido van Rossum: neopythonic.blogspot.com/2008/10/…
unutbu

14
Vedi anche "Perché 'self' deve essere usato esplicitamente nelle definizioni e nelle chiamate dei metodi": docs.python.org/faq/…
unutbu

37
"Che capisco, abbastanza facilmente" --- Abbastanza soggettivo, non credi? Cosa rende @namepiù intuitivo di self.name? Quest'ultimo, IMO, è più intuitivo.
Santa,

14
Questa è la differenza chiave tra una funzione e un metodo di classe. Una funzione è libera, libera. Un metodo di classe (istanza) deve essere consapevole del suo genitore (e delle proprietà del genitore), quindi è necessario passare al metodo un riferimento alla classe genitore (come ). È solo una regola meno implicita che devi interiorizzare prima di capire OOP. Altre lingue scelgono lo zucchero sintattico sulla semplicità semantica, il pitone non è altre lingue.
Evan Plaice,

9
Non credo che "esplicito sia meglio di implicito" spieghi davvero bene questa scelta progettuale. @fooe self.foosono ugualmente espliciti in quanto non deve verificarsi una risoluzione implicita (ad esempio in C ++, è possibile accedere "implicitamente" ai membri dell'istanza senza "esplicitamente" utilizzare gli spazi dei nomi). L'unica differenza è che Ruby introduce un nuovo semantico (@), mentre Python no. Il fatto che un nuovo semantico valga o meno la quantità di verbosità evitata è puramente soggettivo. Tuttavia, va notato che la maggior parte delle lingue moderne sceglie di introdurre qui un concetto (ad esempio php è $ this, JS è questo).
Jing

Risposte:


710

Il motivo che è necessario utilizzare self.è perché Python non utilizza la @sintassi per fare riferimento agli attributi dell'istanza. Python ha deciso di eseguire i metodi in modo tale che l'istanza a cui appartiene il metodo venga passata automaticamente, ma non ricevuta automaticamente: il primo parametro dei metodi è l'istanza su cui viene chiamato il metodo. Ciò rende i metodi completamente uguali alle funzioni e lascia il nome effettivo da usare fino a te (anche se selfè la convenzione, e le persone generalmente ti guarderanno male quando usi qualcos'altro.) selfNon è speciale per il codice, è solo un altro oggetto .

Python avrebbe potuto fare qualcos'altro per distinguere i nomi normali dagli attributi - sintassi speciale come ha fatto Ruby, o richiedere dichiarazioni come C ++ e Java, o forse qualcosa di ancora più diverso - ma non è così. Python è tutto per rendere esplicite le cose, rendendo ovvio che cosa è cosa, e sebbene non lo faccia del tutto ovunque, lo fa per esempio gli attributi. Ecco perché l'assegnazione a un attributo di istanza deve sapere a quale istanza assegnare e per questo ha bisogno self..


23
@Georg: si clsriferisce all'oggetto classe, non all'oggetto istanza
SilentGhost

17
@SilentGhost: in realtà, il nome del primo parametro è quello che vuoi che sia. Sui metodi di classe, la convenzione deve essere utilizzata clse selfviene utilizzata in modo convenzionale per i metodi di istanza. Se avessi voluto, avrei potuto usare selfper metodi di classe e clsper esempio metodi. Potrei anche usare bobe fnordse mi piaceva.
SingleNegationElimination,

67
Trovo interessante che la community non abbia scelto thisinvece di self. Ha selfun po 'di storia di cui non sono a conoscenza nei vecchi linguaggi di programmazione?
Jules GM

24
@Julius selfVenne dalle convenzioni di Modula-3, vedi questa risposta per ulteriori dettagli su questa scelta. (Dichiarazione di non responsabilità: la mia).
Bakuriu,

9
@Julius La selfparola chiave (Smalltalk, 1980) precede la thisparola chiave (da C ++). Vedi: stackoverflow.com/questions/1079983/…
Wes Turner

425

Prendiamo una semplice classe vettoriale:

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

Vogliamo avere un metodo che calcoli la lunghezza. Come sarebbe se volessimo definirlo all'interno della classe?

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

Come dovrebbe apparire quando dovremmo definirlo un metodo / funzione globale?

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

Quindi l'intera struttura rimane la stessa. Come posso farne uso? Se supponiamo per un momento di non aver scritto un lengthmetodo per la nostra Vectorclasse, potremmo farlo:

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

Questo funziona perché il primo parametro di length_global, può essere riutilizzato come selfparametro in length_new. Ciò non sarebbe possibile senza un esplicito self.


Un altro modo di comprendere la necessità dell'esplicito selfè vedere dove Python aggiunge un po 'di zucchero sintattico. Quando tieni a mente, in pratica, una chiamata simile

v_instance.length()

viene trasformato internamente in

Vector.length(v_instance)

è facile vedere dove si selfadatta. In realtà non si scrivono metodi di istanza in Python; ciò che scrivi sono metodi di classe che devono prendere un'istanza come primo parametro. Pertanto, dovrai posizionare il parametro dell'istanza in modo esplicito da qualche parte.


4
Vector.length_new = length_global ... In realtà ho iniziato a usare la sintassi in questo modo nelle mie dichiarazioni di classe. Ogni volta che voglio solo ereditare alcuni dei metodi da un'altra classe, copio esplicitamente il riferimento ai metodi.
Jeeyoung Kim,

2
sarebbe giusto dire che il "metodo di istanza" di Python è semplicemente uno zucchero sintattico di metodi globali statici (come in Java o C ++) con un oggetto di istanza passato per impacchettare più attributi? --- beh, questo è un po 'semi-vero poiché nel polimorfismo, lo scopo più importante di "questo" (come in java) o "sé" è darti la corretta implementazione dei metodi. Python ha questo. quindi chiamare myobj.someMethod () è uguale a TheClassOfMyObj.someMethod (myobj) in python. nota che "TheClassOfMyObj" viene automaticamente capito da Python da "sé", altrimenti dovresti scoprirlo.
teddy teddy

3
Infatti, non solo i metodi di istanza sono solo metodi di classe, ma i metodi sono solo funzioni che sono membri di una classe, come Vector.length_new = length_globalmostra.
RussW,

1
"Questo funziona, perché il primo parametro di length_global, può essere riutilizzato come parametro di sé in length_new. Ciò non sarebbe possibile senza un sé esplicito." - Funzionerebbe lo stesso. verrebbe riutilizzato per il sé implicito ... il secondo esempio è un ragionamento circolare - devi posizionare esplicitamente il sé lì, perché Python ha bisogno del sé esplicito.
Karoly Horvath,

1
@KarolyHorvath: Certo, sarebbe anche possibile avere una lingua con un modello in cui i metodi definiti internamente non hanno bisogno di un sé esplicito, ma i metodi definiti esternamente lo fanno. Ma direi che c'è una certa coerenza nel richiedere il sé esplicito in entrambi i casi, il che lo rende un motivo legittimo per farlo in questo modo. Altre lingue possono scegliere approcci diversi.
Debilski,

422

Supponiamo che tu abbia una classe ClassAche contiene un metodo methodAdefinito come:

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

ed ObjectAè un'istanza di questa classe.

Ora quando ObjectA.methodA(arg1, arg2)viene chiamato, Python lo converte internamente per te come:

ClassA.methodA(ObjectA, arg1, arg2)

La selfvariabile si riferisce all'oggetto stesso.


94
Ho letto tutte le altre risposte e ho capito, ho letto questa e poi ha avuto un senso.
Seth,

3
Questo mi ha inchiodato!
Bernard "Beta Berlin" Parah,

2
Perché non tenere quelle viscere dentro, però, come fa Ruby?
Cees Timmerman,

Ma nel metodo __init __ (self), accetta self, quindi anche senza creare l'oggetto, come si riferisce a se stesso?
saurav,

Seriamente, questo è molto meglio dell'esempio di Debilski perché non è eccessivamente complesso e le persone potrebbero non avere familiarità con i vettori.
NoName,

215

Quando gli oggetti vengono istanziati, l'oggetto stesso viene passato nel parametro auto.

inserisci qui la descrizione dell'immagine

Per questo motivo, i dati dell'oggetto sono associati all'oggetto. Di seguito è riportato un esempio di come potresti visualizzare l'aspetto dei dati di ciascun oggetto. Notare come 'self' viene sostituito con il nome degli oggetti. Non sto dicendo che questo diagramma di esempio qui sotto è del tutto accurato, ma si spera con uno scopo nel visualizzare l'uso di sé.

inserisci qui la descrizione dell'immagine

L'oggetto viene passato nel parametro self in modo che l'oggetto possa conservare i propri dati.

Anche se questo potrebbe non essere del tutto accurato, pensa al processo di creazione di un'istanza di un oggetto come questo: quando un oggetto viene creato, utilizza la classe come modello per i propri dati e metodi. Senza passare il proprio nome nel parametro personale, gli attributi e i metodi nella classe rimarrebbero come modello generale e non farebbero riferimento a (appartengono a) l'oggetto. Quindi, passando il nome dell'oggetto nel parametro auto significa che se 100 oggetti vengono istanziati da una classe, tutti possono tenere traccia dei propri dati e metodi.

Vedi l'illustrazione seguente:

inserisci qui la descrizione dell'immagine


Ehilà, quando si accede agli attributi di Bob, ad esempio con "bob.name ()", si accede effettivamente a bob (). Self.name per così dire dal ' init ' giusto?
udarH3

3
Quando scrivi bob.name () nel commento sopra, stai insinuando che bob ha un metodo chiamato name () a causa del fatto che hai aggiunto parentesi dopo il nome. In questo esempio tuttavia non esiste tale metodo. 'bob.name' (che non ha parentesi) sta accedendo direttamente all'attributo chiamato name dal metodo init (costruttore). Quando viene chiamato il metodo speak di bob, è il metodo che accede all'attributo name e lo restituisce in un'istruzione print. Spero che sia di aiuto.
sw123456,

3
No, ottieni il valore di self.name, che per l'oggetto bob è in realtà bob.name, perché il nome dell'oggetto viene passato al parametro self quando viene creato (istanziato). Ancora una volta, spero che questo aiuti. Sentiti libero di votare il post principale se lo ha.
sw123456,

2
Il nome viene assegnato a self.name all'istanza. Dopo aver creato un oggetto, tutte le variabili che appartengono all'oggetto sono quelle precedute da 'self'. Ricorda che self viene sostituito con il nome dell'oggetto quando viene creato dalla classe.
sw123456,

5
Ecco come spieghi le cose! bel lavoro :)
penta,

80

Mi piace questo esempio:

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: []

18
quindi var senza sé è semplicemente statico varas di classe, come in java
teddy teddy

5
orsacchiotto, non sei del tutto corretto. Il comportamento (statico o non statico) dipende non solo dal selftipo di variabile. Prova a fare il primo esempio con un numero intero anziché un elenco. Il risultato sarebbe abbastanza diverso.
Konstantin,

2
In realtà, la mia domanda con questo è perché sei autorizzato a dire a.foonel primo esempio, piuttosto che A.foo? fooAppartiene chiaramente alla classe ...
Radon Rosborough,

È possibile chiamare membri statici dalle istanze dell'oggetto nella maggior parte delle lingue. Perché è sorprendente?
Paarth,

2
@RadonRosborough Perché nel primo esempio, ae bsono entrambe le etichette (o puntatori) per A()(la classe). a.foofa riferimento al A().foometodo di classe. Nel secondo esempio, tuttavia, adiventa un riferimento a un'istanza di A(), come fa b. Ora che sono istanze anziché l'oggetto classe stesso, self consente al foometodo di operare sulle istanze.
LegendaryDude,

40

Dimostrerò con il codice che non usa le classi :

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'

Le classi sono solo un modo per evitare di passare continuamente in questo "stato" (e altre cose carine come l'inizializzazione, la composizione della classe, le metaclasse raramente necessarie e il supporto di metodi personalizzati per sovrascrivere gli operatori).

Ora dimostriamo il codice sopra usando il macchinario di classe python integrato, per mostrare come sia sostanzialmente la stessa cosa.

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 )

[ha migrato la mia risposta da una domanda chiusa duplicata]


1
Vorrei che Python rivestisse di zucchero i gestori e Ruby.
Cees Timmerman,

20

I seguenti estratti sono tratti dalla documentazione di Python sull'auto :

Come in Modula-3, non ci sono scorciatoie [in Python] per fare riferimento ai membri dell'oggetto dai suoi metodi: la funzione metodo è dichiarata con un primo argomento esplicito che rappresenta l'oggetto, che è fornito implicitamente dalla chiamata.

Spesso, il primo argomento di un metodo si chiama self. Questo non è altro che una convenzione: il nome sé non ha assolutamente alcun significato speciale per Python. Si noti, tuttavia, che non seguendo la convenzione il codice potrebbe essere meno leggibile da altri programmatori Python, ed è anche ipotizzabile che possa essere scritto un programma browser di classe che si basi su tale convenzione.

Per ulteriori informazioni, consultare l' esercitazione sulla documentazione di Python sulle classi .


20

Oltre a tutti gli altri motivi già indicati, consente un accesso più semplice ai metodi ignorati; puoi chiamare Class.some_method(inst).

Un esempio di dove è utile:

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

Il suo uso è simile all'uso della thisparola chiave in Java, ovvero per fornire un riferimento all'oggetto corrente.


2
class myClass: def myFunc (this, name): this.name = name
LEMUEL ADANE

16

Python non è un linguaggio creato per la programmazione orientata agli oggetti a differenza di Java o C ++.

Quando si chiama un metodo statico in Python, si scrive semplicemente un metodo con argomenti regolari al suo interno.

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

Tuttavia, un metodo oggetto, che richiede di creare una variabile, che è un animale, in questo caso, ha bisogno dell'argomento personale

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

Il metodo self viene anche utilizzato per fare riferimento a un campo variabile all'interno della classe.

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


    def getAnimalName(self):
        return self.animalName

In questo caso, self si riferisce alla variabile animalName dell'intera classe. RICORDA: se hai una variabile all'interno di un metodo, il sé non funzionerà. Quella variabile è semplicemente esistente solo mentre quel metodo è in esecuzione. Per definire i campi (le variabili dell'intera classe), è necessario definirli FUORI i metodi della classe.

Se non capisci una sola parola di ciò che sto dicendo, allora Google "Programmazione orientata agli oggetti". Una volta capito questo, non avrai nemmeno bisogno di porre quella domanda :).


+1 a causa della distinzione tra staticMethod()e objectMethod(self). Vorrei aggiungere che per invocare il primo, diresti Animal.staticMethod(), mentre ha objectMethod()bisogno di un'istanza:a = Animal(); a.objectMethod()
Laryx Decidua,

Quello che stai dicendo non è vero al 100%. Questa è solo una convenzione. Puoi ancora chiamare il metodo statico da un oggetto creato. Non sarai in grado di usare nessun membro della classe perché non hai dichiarato un sé. Posso anche chiamare Animal.objectMethod (animalObj) per chiamare il non statico. Fondamentalmente questo significa che un metodo statico è solo un metodo che non utilizza le variabili membro. Non dovrebbe esserci alcuna necessità di dichiararsi. Penso che sia un linguaggio sciocco. Lingue come Lua e C ++ offrono variabili obj dietro le quinte.
user441521

Hai fatto una dichiarazione di stringa animalName inutile e un metodo animalName in crash.
Cees Timmerman,

3
@ytpillai Irrilevant. Il codice confuso e errato non deve essere presentato come una risposta.
Cees Timmerman,

1
def getAnimalNameper non ostruire la stringa che stai tentando di restituire e selffa riferimento all'istanza della classe, non a nessun campo al suo interno.
Cees Timmerman,

10

È lì per seguire lo zen di Python "esplicito è meglio che implicito". È davvero un riferimento al tuo oggetto di classe. In Java e PHP, ad esempio, viene chiamato this.

Se user_type_nameè presente un campo sul tuo modello, puoi accedervi self.user_type_name.


10

Prima di tutto, sé è un nome convenzionale, potresti mettere qualsiasi altra cosa (essere coerente) al suo posto.

Si riferisce all'oggetto stesso, quindi quando lo stai usando, dichiari che .name e .age sono proprietà degli oggetti Student (nota, non della classe Student) che stai per creare.

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

Il codice è qui


1
La tua risposta mi sembra la più chiara. +1
Pawel

9

selfè un riferimento all'oggetto stesso, quindi sono uguali. I metodi Python non vengono chiamati nel contesto dell'oggetto stesso. selfin Python può essere usato per gestire modelli di oggetti personalizzati o qualcosa del genere.


8

L'uso dell'argomento, chiamato convenzionalmente, selfnon è così difficile da capire, come è perché è necessario? O sul perché menzionarlo esplicitamente? Questa, suppongo, è una domanda più grande per la maggior parte degli utenti che cercano questa domanda, o se non lo è, avranno sicuramente la stessa domanda mentre avanzano imparando Python. Consiglio loro di leggere questi due blog:

1: uso di sé spiegato

Nota che non è una parola chiave.

Il primo argomento di ogni metodo di classe, incluso init, è sempre un riferimento all'istanza corrente della classe. Per convenzione, questo argomento è sempre chiamato sé. Nel metodo init, self si riferisce all'oggetto appena creato; in altri metodi di classe, si riferisce all'istanza il cui metodo è stato chiamato. Ad esempio, il codice seguente è uguale al codice sopra.

2: Perché lo facciamo in questo modo e perché non possiamo eliminarlo come argomento, come Java, e avere invece una parola chiave

Un'altra cosa che vorrei aggiungere è che un selfargomento facoltativo mi consente di dichiarare metodi statici all'interno di una classe, non scrivendo self.

Esempi di codice:

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 : funziona solo in Python 3.x.

Nelle versioni precedenti, è necessario aggiungere esplicitamente @staticmethoddecoratore, altrimenti l' selfargomento è obbligatorio.


7

Sono sorpreso che nessuno abbia allevato Lua. Lua usa anche la variabile 'self', tuttavia può essere omessa ma ancora utilizzata. C ++ fa lo stesso con 'this'. Non vedo alcun motivo per dover dichiarare 'self' in ciascuna funzione, ma dovresti comunque essere in grado di usarlo come puoi con lua e C ++. Per un linguaggio che si vanta di essere breve è strano che ti richieda di dichiarare l'auto-variabile.


6

Dai un'occhiata al seguente esempio, che spiega chiaramente lo scopo di 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 è usato / necessario per distinguere tra istanze.

Fonte: spiegazione automatica di Python - Pythontips


Sì, penso che sappiamo perché si usa il sé, ma la domanda è: perché la lingua ti fa dichiarare esplicitamente. Molte altre lingue non richiedono questo e un linguaggio che si vanta di essere breve, penseresti che ti darebbero semplicemente la variabile dietro le quinte da usare come Lua o C ++ (questo).
user441521,

3
@ kmario23 La tua risposta è stata da qui: pythontips.com/2013/08/07/the-self-variable-in-python-explained Ti preghiamo di riconoscere sempre gli autori originali quando pubblichi risposte come tue.
geekidharsh,

@geekidharsh grazie, ho aggiunto una nota!
kmario23

5

È perché dal modo in cui è progettato Python le alternative difficilmente funzionerebbero. Python è progettato per consentire la definizione di metodi o funzioni in un contesto in cui sia implicito this(a-la Java / C ++) sia esplicito @(a-la ruby) non funzionerebbe. Facciamo un esempio con l'approccio esplicito con le convenzioni di Python:

def fubar(x):
    self.x = x

class C:
    frob = fubar

Ora la fubarfunzione non funzionerebbe poiché presuppone che si selftratti di una variabile globale (e frobanche in). L'alternativa sarebbe quella di eseguire i metodi con un ambito globale sostituito (dove si selftrova l'oggetto).

L'approccio implicito sarebbe

def fubar(x)
    myX = x

class C:
    frob = fubar

Ciò significherebbe che myXsarebbe interpretato come una variabile locale in fubar(e frobanche in). L'alternativa qui sarebbe quella di eseguire metodi con un ambito locale sostituito che viene mantenuto tra le chiamate, ma ciò rimuove la possibilità delle variabili locali del metodo.

Tuttavia la situazione attuale funziona bene:

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

 class C:
     frob = fubar

qui quando chiamato come metodo frobriceverà l'oggetto su cui viene chiamato tramite il selfparametro, e fubarpuò ancora essere chiamato con un oggetto come parametro e funziona allo stesso modo ( è lo stesso C.frobche penso).


3

Nel __init__metodo, self si riferisce all'oggetto appena creato; in altri metodi di classe, si riferisce all'istanza il cui metodo è stato chiamato.

sé, come nome, è solo una convenzione , chiamalo come vuoi! ma quando lo si utilizza, ad esempio per eliminare l'oggetto, è necessario utilizzare lo stesso nome:, __del__(var)dove è varstato utilizzato in__init__(var,[...])

Dovresti dare un'occhiata clsanche a, per avere un quadro più ampio . Questo post potrebbe essere utile.


3

self si comporta come il nome dell'oggetto corrente o l'istanza della classe.

# 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

1

self è inevitabile.

C'era solo una domanda dovrebbe selfessere implicita o esplicita. Guido van Rossumrisolto questo problema dicendo che selfdoveva rimanere .

Quindi dove selfvive?

Se dovessimo semplicemente attenerci alla programmazione funzionale non avremmo bisogno self. Una volta entrati nel Python OOP lo troviamo selflì.

Ecco il tipico caso d'uso class Ccon il metodom1

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

Questo programma produrrà:

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

Quindi selfcontiene l'indirizzo di memoria dell'istanza di classe. Lo scopo di selfsarebbe quello di tenere il riferimento per metodi di istanza e per noi avere esplicitamente l'accesso a quella di riferimento.


Nota: esistono tre diversi tipi di metodi di classe:

  • metodi statici (leggi: funzioni),
  • metodi di classe,
  • metodi di istanza (menzionati).

0

dai documenti ,

la particolarità dei metodi è che l'oggetto di istanza viene passato come primo argomento della funzione. Nel nostro esempio, la chiamata x.f()è esattamente equivalente a MyClass.f(x). In generale, chiamare un metodo con un elenco di n argomenti equivale a chiamare la funzione corrispondente con un elenco di argomenti creato inserendo l'oggetto di istanza del metodo prima del primo argomento.

prima di questo lo snippet correlato,

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

    def f(self):
        return 'hello world'

x = MyClass()


-2

è un riferimento esplicito all'oggetto istanza della classe.


21
Non penso che questo aiuti Richzilla a capire il motivo dietro.
Georg Schölly,

1
@SilentGhost: l'hai inchiodato. Sono impressionato. se lo capisco correttamente: creo un oggetto come istanza della classe definita e il parametro stesso si riferisce a quell'oggetto? Capisco che il sé si riferisce in modo implicito alla classe stessa, ma sarebbe bello se spiegassi un po 'di più la tua risposta.
dkrynicki,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.