Wat is het doel van het woord ‘zelf’?

Wat is het doel van het woord selfin Python? Ik begrijp dat het verwijst naar het specifieke object dat uit die klasse is gemaakt, maar ik begrijp niet waarom het expliciet als parameter aan elke functie moet worden toegevoegd. Ter illustratie, in Ruby kan ik dit doen:

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

Wat ik begrijp, vrij gemakkelijk. In Python moet ik echter selfopnemen:

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

Kan iemand me hier doorheen praten? Het is niet iets dat ik ben tegengekomen in mijn (weliswaar beperkte) ervaring.


Antwoord 1, autoriteit 100%

De reden dat u self.moet gebruiken, is omdat Python de syntaxis @niet gebruikt om naar instantieattributen te verwijzen. Python heeft ervoor gekozen om methoden zo te gebruiken dat de instantie waartoe de methode behoort automatisch wordt doorgegeven, maar niet automatisch ontvangen: de eerste parameter van methoden is de instantie de methode wordt aangeroepen. Dat maakt methoden volledig hetzelfde als functies, en laat de daadwerkelijke naam aan jou over (hoewel selfde conventie is, en mensen zullen over het algemeen fronsend naar je kijken als je iets anders gebruikt.) selfis niet speciaal voor de code, het is gewoon een ander object.

Python had iets anders kunnen doen om normale namen van attributen te onderscheiden — een speciale syntaxis zoals Ruby heeft, of declaraties zoals C++ en Java vereisen, of misschien nog iets anders — maar dat gebeurde niet. Python is er helemaal voor om dingen expliciet te maken, duidelijk te maken wat wat is, en hoewel het het niet overal helemaal doet, doet het het wel, bijvoorbeeld attributen. Daarom moet het toewijzen aan een instantiekenmerk weten aan welke instantie het moet worden toegewezen, en daarom heeft het self.nodig.


Antwoord 2, autoriteit 68%

Stel dat je een klasse ClassAhebt die een methode methodAbevat die is gedefinieerd als:

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

en ObjectAis een instantie van deze klasse.

Als nu ObjectA.methodA(arg1, arg2)wordt aangeroepen, converteert python het intern voor je als:

ClassA.methodA(ObjectA, arg1, arg2)

De variabele selfverwijst naar het object zelf.


Antwoord 3, autoriteit 58%

Laten we een eenvoudige vectorklasse nemen:

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

We willen een methode hebben die de lengte berekent. Hoe zou het eruit zien als we het binnen de klas zouden willen definiëren?

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

Hoe zou het eruit moeten zien als we het zouden definiëren als een globale methode/functie?

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

Dus de hele structuur blijft hetzelfde. Hoe kan ik hier gebruik van maken? Als we even aannemen dat we geen methode lengthvoor onze klasse Vectorhebben geschreven, kunnen we dit doen:

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

Dit werkt omdat de eerste parameter van length_globalopnieuw kan worden gebruikt als de parameter selfin length_new. Dit zou niet mogelijk zijn zonder een expliciete self.


Een andere manier om de behoefte aan het expliciete selfte begrijpen, is door te kijken waar Python wat syntactische suiker toevoegt. Als u in gedachten houdt, dat in feite een oproep als

v_instance.length()

is intern getransformeerd naar

Vector.length(v_instance)

het is gemakkelijk te zien waar de selfpast. In Python schrijft u eigenlijk geen instantiemethoden; wat je schrijft zijn klassenmethoden die een instantie als eerste parameter moeten nemen. En daarom moet je de instantieparameter ergens expliciet plaatsen.


Antwoord 4, autoriteit 31%

Wanneer objecten worden geïnstantieerd, wordt het object zelf doorgegeven aan de parameter self.

Hierdoor wordt het object gegevens zijn gebonden aan het object. Hieronder is een voorbeeld van hoe je misschien leuk om te visualiseren welke gegevens van elk object eruit zou kunnen zien. Merk op hoe ‘zelf’ is vervangen door de naam van objecten. Ik zeg niet dat dit voorbeeld schema hieronder is geheel accuraat, maar het hopelijk met dienen een doel in het visualiseren van het gebruik van het zelf.

Het object wordt in de eigen parameter zodat het object greep van zijn eigen gegevens kan houden doorgegeven.

Hoewel dit niet geheel accuraat kunnen zijn, denk aan het proces van het instantiëren van een object als volgt: Wanneer een object is gemaakt wordt de klasse als een sjabloon voor zijn eigen gegevens en methoden. Zonder het passeren van zijn eigen naam in het zelf parameter, zou de attributen en methoden in de klas als een algemene sjabloon te blijven en zou niet worden gerelateerd aan (behoren te) het object. Dus door het passeren van de naam van het object in de eigen parameter betekent dat als 100 objecten worden geconcretiseerd van de ene klasse, ze kunnen allemaal bijhouden van hun eigen gegevens en methoden.

Zie de afbeelding hieronder:


Antwoord 5, Autoriteit 11%

ik op dit voorbeeld:

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

Antwoord 6, Autoriteit 6%

Ik zal aantonen met code die maakt geen gebruik van de klassen

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'

Klassen zijn slechts een manier om te voorkomen dat je de hele tijd in dit “status”-ding gaat (en andere leuke dingen zoals initialiseren, klassensamenstelling, de zelden benodigde metaklassen en ondersteuning van aangepaste methoden om operators te overschrijven).

Laten we nu de bovenstaande code demonstreren met behulp van de ingebouwde machine van de Python-klasse, om te laten zien dat het in wezen hetzelfde is.

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 )

[mijn antwoord gemigreerd van dubbele gesloten vraag]


Antwoord 7, autoriteit 3%

De volgende fragmenten zijn afkomstig uit de Python-documentatie over zichzelf:

Net als in Modula-3 zijn er geen afkortingen [in Python] om te verwijzen naar de leden van het object vanuit zijn methoden: de methode-functie wordt gedeclareerd met een expliciet eerste argument dat het object vertegenwoordigt, dat impliciet wordt geleverd door de aanroep.

p>

Vaak wordt het eerste argument van een methode self genoemd. Dit is niets meer dan een conventie: de naam zelf heeft absoluut geen speciale betekenis voor Python. Houd er echter rekening mee dat door het niet volgen van de conventie uw code mogelijk minder leesbaar is voor andere Python-programmeurs, en het is ook denkbaar dat er een klassenbrowserprogramma wordt geschreven dat op een dergelijke conventie vertrouwt.

Zie voor meer informatie de python documentatie tutorial op klassen .


Antwoord 8, Autoriteit 3%

en alle andere reeds vermelde redenen, maakt het gemakkelijker toegang tot overgedragen methoden; U kunt Class.some_method(inst)bellen.

Een voorbeeld van waar het nuttig is:

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"

Antwoord 9, Autoriteit 2%

Het gebruik ervan is vergelijkbaar met het gebruik van thistrefwoord in Java, d.w.z. om een ​​verwijzing naar het huidige object te geven.


Antwoord 10, Autoriteit 2%

Python is geen taal die is gebouwd voor objectgeoriënteerde programmering in tegenstelling tot Java of C++.

Bij het bellen van een statische methode in Python schrijft men eenvoudig een methode met reguliere argumenten erin.

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

Een objectmethode, die vereist dat u een variabele maakt, die in dit geval een dier is, heeft het zelfargument

nodig

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

De zelfmethode wordt ook gebruikt om te verwijzen naar een variabele veld binnen de klas.

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

In dit geval verwijst self naar de variabele animalName van de hele klasse. DENK ERAAN: Als je een variabele binnen een methode hebt, zal self niet werken. Die variabele bestaat eenvoudigweg alleen terwijl die methode wordt uitgevoerd. Voor het definiëren van velden (de variabelen van de hele klasse), moet je ze BUITEN de klassenmethoden definiëren.

Als u geen enkel woord begrijpt van wat ik zeg, Google dan op ‘Objectgeoriënteerd programmeren’. Als je dit eenmaal begrijpt, hoef je die vraag niet eens meer te stellen :).


Antwoord 11

selfis een objectreferentie naar het object zelf, daarom zijn ze hetzelfde.
Python-methoden worden niet aangeroepen in de context van het object zelf.
selfin Python kan worden gebruikt om met aangepaste objectmodellen om te gaan of zoiets.


Antwoord 12

Het is er om de Python-zen te volgen “expliciet is beter dan impliciet”. Het is inderdaad een verwijzing naar je klasseobject. In Java en PHP heet het bijvoorbeeld this.

Als user_type_nameeen veld op uw model is, opent u het via self.user_type_name.


Antwoord 13

Allereerst is zelf een conventionele naam, je zou er iets anders (coherent aan) voor in de plaats kunnen zetten.

Het verwijst naar het object zelf, dus als je het gebruikt, verklaar je dat .name en .age eigenschappen zijn van de Student-objecten (let op, niet van de Student-klasse) die je gaat maken.

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

code is hier


Antwoord 14

Ik ben verrast dat niemand Lua heeft opgebracht. Lua gebruikt ook de ‘zelf’-variabele, maar het kan worden weggelaten, maar nog steeds gebruikt. C++ doet hetzelfde met ‘dit’. Ik zie geen enkele reden om ‘zelf’ in elke functie te moeten declareren, maar je moet het nog steeds zoals je kunt gebruiken met Lua en C++. Voor een taal die probeert op het kort te zijn, is het vreemd dat het vereist dat u de zelfvariabele verklaart.


Antwoord 15

Het gebruik van het argument, conventioneel genoemd selfis niet zo moeilijk te begrijpen, zoals is waarom is het noodzakelijk? Of waarom zou het expliciet noemen? Dat, denk ik, is een grotere vraag voor de meeste gebruikers die deze vraag opzoeken, of als dat niet het geval is, zullen ze zeker dezelfde vraag hebben terwijl ze vooruitgaan met het leren van Python. Ik raad ze aan om deze paar blogs te lezen:

1: gebruik van zelf uitgelegd

Merk op dat het geen zoekwoord is.

Het eerste argument van elke klassemethode, inclusief init, is altijd een verwijzing naar de huidige instantie van de klasse. Volgens afspraak wordt dit argument altijd zelf genoemd. In de init-methode verwijst self naar het nieuw gemaakte object; in andere klassenmethoden verwijst het naar de instantie waarvan de methode werd aangeroepen. De onderstaande code is bijvoorbeeld hetzelfde als de bovenstaande code.

2: Waarom hebben we dit dit manier en waarom kunnen we het niet als argument elimineren, zoals Java, en in plaats daarvan een trefwoord gebruiken

Een ander ding dat ik zou willen toevoegen is dat ik met een optioneel selfargument statische methoden binnen een klasse kan declareren, door selfniet te schrijven.

Codevoorbeelden:

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:Dit werkt alleen in Python 3.x.

In eerdere versies moet je expliciet @staticmethoddecorator toevoegen, anders is het selfargument verplicht.


Antwoord 16

Bekijk het volgende voorbeeld, waarin duidelijk het doel van self

wordt uitgelegd

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  

selfwordt gebruikt/nodig om onderscheid te maken tussen instanties.

Bron: zelfvariabele in python uitgelegd – Pythontips


Antwoord 17

Omdat python trouwens is ontworpen, zouden de alternatieven nauwelijks werken. Python is ontworpen om methoden of functies te definiëren in een context waarin zowel impliciete this(a-la Java/C++) als expliciete @(a-la ruby) niet werken. Laten we een voorbeeld nemen met de expliciete benadering met python-conventies:

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

Nu zou de functie fubarniet werken, omdat deze zou aannemen dat selfeen globale variabele is (en ook in frob). Het alternatief zou zijn om methodes uit te voeren met een vervangen globaal bereik (waarbij selfhet object is).

De impliciete benadering zou zijn

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

Dit zou betekenen dat myXzou worden geïnterpreteerd als een lokale variabele in fubar(en ook in frob). Het alternatief hier zou zijn om methoden uit te voeren met een vervangen lokaal bereik dat tussen aanroepen wordt behouden, maar dat zou de mogelijkheid van lokale variabelen van de methode verwijderen.

De huidige situatie pakt echter goed uit:

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

hier, wanneer aangeroepen als een methode, zal frobhet object ontvangen waarop het wordt aangeroepen via de parameter self, en fubarkan nog steeds worden aangeroepen met een object als parameter en hetzelfde werken (het ishetzelfde als C.frobdenk ik).


Antwoord 18

In de __init__methode verwijst self naar het nieuw gecreëerde object; in andere klassenmethoden verwijst het naar de instantie waarvan de methode werd aangeroepen.

zelf, als naam, is slechts een conventie, noem het zoals je wilt! maar wanneer u het gebruikt, bijvoorbeeld om het object te verwijderen, moet u dezelfde naam gebruiken: __del__(var), waarbij varwerd gebruikt in de __init__(var,[...])

Je moet ook naar clskijken om het grotere plaatjete hebben. Deze postkan nuttig zijn.


Antwoord 19

self gedraagt zich als huidige objectnaam of instantie van klasse .

# 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

Antwoord 20

selfis onvermijdelijk.

Er was gewoon een vraagdie selfimpliciet of expliciet zijn.
Guido van Rossumloste deze vraag op met selfmoet blijven.

Dus waar woont het self?

Als we ons alleen maar bij functioneel programmeren zouden houden, zouden we selfniet nodig hebben.
Zodra we de Python OOPinvoeren, vinden we daar self.

Hier is de typische use case class Cmet de methode m1

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

Dit programma zal uitvoeren:

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

Dus selfbevat het geheugenadres van de klasse-instantie.
Het doelvan selfzou zijn om de referentie voor instantiemethodenvast te houden en voor ons om explicietetoegang tot die verwijzing.


Merk op dat er drie verschillende soorten klassenmethoden zijn:

  • statische methoden (lees: functies),
  • klassenmethoden,
  • instantiemethoden (vermeld).

Antwoord 21

het is een expliciete verwijzing naar het klasse-instantieobject.


Antwoord 22

uit de docs,

het bijzondere van methoden is dat het instantieobject wordt doorgegeven als het eerste argument van de functie. In ons voorbeeld is de aanroep x.f()exact gelijk aan MyClass.f(x). Over het algemeen is het aanroepen van een methode met een lijst van n argumenten gelijk aan het aanroepen van de corresponderende functie met een argumentenlijst die is gemaakt door het instantieobject van de methode in te voegen vóór het eerste argument.

voorafgaand aan het gerelateerde fragment,

class MyClass:
    """A simple example class"""
    i = 12345
    def f(self):
        return 'hello world'

x = MyClass()


Antwoord 23

Ik zou in ieder geval voor Python zeggen dat de self-parameter kan worden gezien als een tijdelijke aanduiding.
Kijk hier eens naar:

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age
p1 = Person("John", 36)
print(p1.name)
print(p1.age)

Zelf werd in dit geval en vele anderen gebruikt als een methode om de naamwaarde op te slaan. Daarna gebruiken we echter de p1 om deze toe te wijzen aan de klasse die we gebruiken. Als we het dan afdrukken, gebruiken we hetzelfde p1-sleutelwoord.

Ik hoop dat dit helpt voor Python!


Antwoord 24

“ZELF” trefwoord heeft de referentie van de les en het is tot u als u het wilt gebruiken of niet, maar als u opmerkt, wanneer u een nieuwe methode in Python maakt, schrijft Python automatisch zelfwoord voor u. Als u een aantal R & AMP; D, zult u merken dat als u twee methoden in een klasse zegt, en probeert één in de andere te bellen, het niet herkent de methode, tenzij u zelf (referentie van de les) toevoegt.

class testA:
def __init__(self):
    print('ads')
def m1(self):
    print('method 1')
    self.m2()
def m2(self):
    print('method 2')

Onderstaande code gooit geen enkele referentiefout.

class testA:
def __init__(self):
    print('ads')
def m1(self):
    print('method 1')
    m2()  #throws unresolvable reference error as class does not know if m2 exist in class scope
def m2(self):
    print('method 2')

Let nu zie hieronder voorbeeld

class testA:
def __init__(self):
    print('ads')
def m1(self):
    print('method 1')
def m2():
    print('method 2')

Nu, wanneer u een object van de klasse Testa maakt, kunt u methode m1 () bellen met klassenobject zoals deze als methode M1 () heeft zelf zoekwoord

obj = testA()
obj.m1()

Maar als u methode M2 ​​() wilt bellen, omdat het geen zelfreferentie heeft, zodat u M2 () rechtstreeks kunt bellen met behulp van klassenaam zoals hieronder

testA.m2()

Maar blijf in de praktijk om met zelfwoord te leven, omdat er ook andere voordelen ervan zijn, zoals het creëren van globale variabele binnen enzovoort.


Antwoord 25

mijn kleine 2 cent

In deze klasse Persoon hebben we de init-methode gedefinieerd met het zelf en interessant om op te merken is de geheugenlocatie van zowel het zelfals de instantievariabele pis hetzelfde <__main__.Person object at 0x106a78fd0>

class Person:
    def __init__(self, name, age):
        self.name = name 
        self.age = age 
    def say_hi(self):
        print("the self is at:", self)
        print((f"hey there, my name is {self.name} and I am {self.age} years old"))
    def say_bye(self):
        print("the self is at:", self)
        print(f"good to see you {self.name}")
p = Person("john", 78)
print("the p is at",p)
p.say_hi()  
p.say_bye() 

dus zoals hierboven uitgelegd, zijn zowel de zelf- als de instantievariabele hetzelfde object.


Antwoord 26

Het woord ‘zelf’ verwijst naar een instantie van een klasse

class foo:
      def __init__(self, num1, num2):
             self.n1 = num1 #now in this it will make the perimeter num1 and num2 access across the whole class
             self.n2 = num2
      def add(self):
             return self.n1 + self.n2 # if we had not written self then if would throw an error that n1 and n2 is not defined and we have to include self in the function's perimeter to access it's variables

Other episodes