Frage Was ist der Zweck des Selbst?


Was ist der Zweck der self Wort in Python? Ich verstehe, dass es sich auf das spezifische Objekt bezieht, das von dieser Klasse erzeugt wird, aber ich kann nicht verstehen, warum es explizit jeder Funktion als Parameter hinzugefügt werden muss. Zur Veranschaulichung kann ich in Ruby Folgendes tun:

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

Was ich leicht verstehe. Allerdings muss ich in Python aufnehmen self:

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

Kann mir jemand darüber reden? Es ist nicht etwas, auf das ich in meiner (zugegebenermaßen begrenzten) Erfahrung gestoßen bin.


883
2018-04-25 20:22


Ursprung


Antworten:


Der Grund, den Sie verwenden müssen self. ist, weil Python das nicht benutzt @ Syntax für Instanzattribute. Python entschied sich dafür, Methoden so auszuführen, dass die Instanz, zu der die Methode gehört, erstellt wird bestanden automatisch, aber nicht empfangen automatisch: Der erste Parameter von Methoden ist die Instanz, in der die Methode aufgerufen wird. Das macht Methoden völlig gleich wie Funktionen und lässt den tatsächlichen Namen, um zu Ihnen zu verwenden (obwohl self ist die Konvention, und die Leute werden dir generell die Stirn runzeln, wenn du etwas anderes benutzt.) self ist nicht speziell für den Code, es ist nur ein anderes Objekt.

Python hätte etwas anderes tun können, um normale Namen von Attributen zu unterscheiden - spezielle Syntax wie Ruby oder Deklarationen wie C ++ und Java oder vielleicht noch etwas anderes -, aber das tat es nicht. Python ist alles dafür, Dinge explizit zu machen, was es offensichtlich macht, was es ist, und obwohl es das nicht überall tut, tut es das für Instanzattribute. Aus diesem Grund muss die Zuweisung an ein Instanzattribut wissen, welcher Instanz es zuzuweisen ist und deshalb benötigt es self..


584
2018-04-25 20:25



Nehmen wir eine einfache Vektorklasse:

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

Wir wollen eine Methode haben, die die Länge berechnet. Wie würde es aussehen, wenn wir es innerhalb der Klasse definieren möchten?

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

Wie sollte es aussehen, wenn wir es als globale Methode / Funktion definieren?

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

So bleibt die gesamte Struktur gleich. Wie kann ich das nutzen? Wenn wir für einen Moment annehmen, dass wir nicht geschrieben haben length Methode für unsere Vector Klasse, könnten wir das tun:

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

Dies funktioniert, weil der erste Parameter von length_global, kann als das wiederverwendet werden self Parameter in length_new. Dies wäre ohne eine explizite nicht möglich self.


Eine weitere Möglichkeit, das Bedürfnis nach Explizitem zu verstehen self ist zu sehen, wo Python etwas syntaktischen Zucker hinzufügt. Wenn Sie daran denken, dass im Grunde ein Anruf wie

v_instance.length()

wird intern in umgewandelt

Vector.length(v_instance)

Es ist leicht zu sehen, wo self passt dazu. Sie schreiben keine Instanzmethoden in Python. Was Sie schreiben, sind Klassenmethoden, die eine Instanz als ersten Parameter annehmen müssen. Daher müssen Sie den Parameter instance explizit platzieren.


382
2018-04-28 00:03



Nehmen wir an, Sie haben eine Klasse ClassA welches eine Methode enthält methodA definiert als:

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

und ObjectA ist eine Instanz dieser Klasse.

Jetzt, wenn ObjectA.methodA(arg1, arg2) heißt, Python konvertiert es intern für Sie als:

ClassA.methodA(ObjectA, arg1, arg2)

Das self Variable bezieht sich auf das Objekt selbst.


283
2018-01-26 17:31



Wenn Objekte instanziiert werden, wird das Objekt selbst in den Parameter self übergeben.

enter image description here

Aus diesem Grund sind die Daten des Objekts an das Objekt gebunden. Unten sehen Sie ein Beispiel, wie Sie gerne visualisieren möchten, wie die Daten jedes Objekts aussehen könnten. Beachten Sie, wie "self" durch den Namen des Objekts ersetzt wird. Ich sage nicht, dass dieses Beispieldiagramm ganz genau ist, aber es hoffentlich einen Zweck hat, den Gebrauch von Selbst zu visualisieren.

enter image description here

Das Objekt wird in den Parameter self übergeben, damit das Objekt seine eigenen Daten behalten kann.

Obwohl dies möglicherweise nicht ganz korrekt ist, sollten Sie sich einen solchen Prozess vorstellen: Wenn ein Objekt erstellt wird, verwendet es die Klasse als Vorlage für seine eigenen Daten und Methoden. Ohne den eigenen Namen in den Parameter self zu übergeben, würden die Attribute und Methoden in der Klasse als allgemeine Vorlage verbleiben und nicht auf das Objekt verweisen. Wenn also der Name des Objekts in den Parameter self übergeben wird, bedeutet dies, dass wenn 100 Objekte aus der einen Klasse instanziiert werden, sie alle ihre eigenen Daten und Methoden verfolgen können.

Siehe die folgende Abbildung:

enter image description here


151
2018-06-28 05:47



Ich mag dieses Beispiel:

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
2018-04-26 16:02



Ich werde mit Code demonstrieren, dass benutzt keine 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 sind nur eine Möglichkeit, die ständige Weitergabe dieser "State" -Dinge zu vermeiden (und andere nette Dinge wie Initialisierung, Klassenzusammensetzung, die selten benötigten Metaklassen und die Unterstützung benutzerdefinierter Methoden zum Überschreiben von Operatoren).

Nun wollen wir den obigen Code anhand der eingebauten Python-Klassen-Maschinerie demonstrieren, um zu zeigen, wie es im Grunde dasselbe ist.

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 )

[migrierte meine Antwort von der doppelten geschlossenen Frage]


33
2018-06-22 00:27



Wie auch alle anderen bereits genannten Gründe ermöglicht es einen leichteren Zugriff auf überschriebene Methoden; Du kannst anrufen Class.some_method(inst).

Ein Beispiel, wo es nützlich ist:

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
2018-04-25 20:31



Die folgenden Auszüge stammen aus der Python-Dokumentation über sich selbst:

Wie in Modula-3 gibt es keine Kürzel [in Python] zur Referenzierung der Mitglieder des Objekts von seinen Methoden: Die Methodenfunktion mit einem expliziten ersten Argumente darstellt, das Objekt deklariert wird, die durch den Aufruf implizit vorgesehen ist.

Oft wird das erste Argument einer Methode als self bezeichnet. Das ist nichts weiter als eine Konvention: Der Name self hat für Python absolut keine besondere Bedeutung. Beachten Sie jedoch, dass durch Nichtbeachtung der Konvention Ihres Code in anderem Python-Programmierer weniger lesbar sein kann, und es ist auch denkbar, dass ein Klasse-Browser-Programm geschrieben werden könnte, dass auf dieser Konvention beruht.

Weitere Informationen finden Sie unter Python-Dokumentation Tutorial zu Klassen.


16
2018-04-25 20:29



Python ist keine Sprache, die für objektorientierte Programmierung im Gegensatz zu Java oder C ++ entwickelt wurde.

Wenn Sie eine statische Methode in Python aufrufen, schreibt man einfach eine Methode mit regulären Argumenten darin.

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

Eine Objektmethode, für die Sie eine Variable erstellen müssen, die in diesem Fall ein Animal ist, benötigt jedoch das Argument self

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

Die self-Methode wird auch verwendet, um auf ein Variablenfeld innerhalb der Klasse zu verweisen.

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


    def getAnimalName(self):
        return self.animalName

In diesem Fall bezieht sich self auf die Variable animalName der gesamten Klasse. ERINNERN SIE SICH: Wenn Sie eine Variable innerhalb einer Methode haben, wird self nicht funktionieren. Diese Variable existiert nur während der Ausführung dieser Methode. Um Felder (die Variablen der gesamten Klasse) zu definieren, müssen Sie sie außerhalb der Klassenmethoden definieren.

Wenn Sie kein einziges Wort von dem verstehen, was ich sage, dann Google "Objektorientierte Programmierung". Sobald Sie das verstanden haben, müssen Sie diese Frage nicht einmal stellen :).


11
2018-05-25 16:04



Seine Verwendung ähnelt der Verwendung von this Schlüsselwort in Java, d. h. um einen Verweis auf das aktuelle Objekt zu geben.


10
2017-08-30 16:37