Was ist der Zweck des self
Wortes in Python? Ich verstehe, dass es sich auf das spezifische Objekt bezieht, das aus dieser Klasse erstellt wurde, aber ich kann nicht verstehen, warum es explizit zu 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 ganz leicht verstehe. In Python muss ich jedoch Folgendes einschließen self
:
class myClass:
def myFunc(self, name):
self.name = name
Kann mir jemand das erklären? Es ist nicht etwas, auf das ich in meiner (zugegebenermaßen begrenzten) Erfahrung gestoßen bin.
@name
intuitiver alsself.name
? Letzteres, IMO, ist intuitiver.@foo
undself.foo
sind ebenso explizit, da keine implizite Auflösung erfolgen muss (z. B. können in C ++ auf Instanzmitglieder "implizit" zugegriffen werden, ohne "explizit" Namespaces zu verwenden). Der einzige Unterschied besteht darin, dass Ruby eine neue Semantik (@) einführt, Python jedoch nicht. Ob eine neue Semantik die vermiedene Ausführlichkeit wert war oder nicht, ist rein subjektiv. Es sollte jedoch beachtet werden, dass die meisten modernen Sprachen hier ein Konzept einführen (z. B. PHPs $ this, JS's this).Antworten:
Der Grund, den Sie verwenden müssen,
self.
ist, dass Python die@
Syntax nicht verwendet , um auf Instanzattribute zu verweisen. Python entschied Methoden in einer Art und Weise zu tun , dass die Instanz zu dem macht die Methode gehört werden weitergegeben automatisch, aber nicht empfangen automatisch: der erste Parameter von Methoden der Instanz ist die Methode aufgerufen wird. Das macht Methoden völlig gleich wie Funktionen und überlässt es Ihnen, den tatsächlichen Namen zu verwenden (obwohl diesself
die Konvention ist und die Leute Sie im Allgemeinen missbilligen, wenn Sie etwas anderes verwenden.). Diesself
ist nichts Besonderes für den Code, sondern nur ein anderes Objekt .Python hätte etwas anderes tun können, um normale Namen von Attributen zu unterscheiden - eine spezielle Syntax wie Ruby oder Deklarationen wie C ++ und Java oder vielleicht etwas noch anderes -, aber das tat es nicht. Python ist alles, um Dinge explizit zu machen, um klar zu machen, was was ist, und obwohl es nicht überall funktioniert, macht es es zum Beispiel für Attribute. Aus diesem Grund muss das Zuweisen zu einem Instanzattribut wissen, welcher Instanz zugewiesen werden soll, und aus diesem Grund muss es zugewiesen werden
self.
.quelle
cls
bezieht sich auf das Klassenobjekt, nicht auf dascls
undself
wird konventionell für beispielsweise Methoden verwendet. Wenn ich wollte, könnte ichself
für Klassenmethoden undcls
zum Beispiel Methoden verwenden. Ich könnte auch verwendenbob
undfnord
wenn ich möchte.this
statt gewählt hatself
. Hatself
eine Geschichte, die mir in älteren Programmiersprachen nicht bekannt ist?self
stammt aus den Konventionen von Modula-3. Weitere Details zu dieser Auswahl finden Sie in dieser Antwort . (Haftungsausschluss: es ist meins).self
Schlüsselwort (Smalltalk, 1980) ist älter als dasthis
Schlüsselwort (aus C ++). Siehe: stackoverflow.com/questions/1079983/…Nehmen wir eine einfache Vektorklasse:
Wir wollen eine Methode, die die Länge berechnet. Wie würde es aussehen, wenn wir es innerhalb der Klasse definieren wollten?
Wie sollte es aussehen, wenn wir es als globale Methode / Funktion definieren würden?
Die gesamte Struktur bleibt also gleich. Wie kann ich das nutzen? Wenn wir für einen Moment annehmen, dass wir keine
length
Methode für unsereVector
Klasse geschrieben haben, könnten wir dies tun:Dies funktioniert, weil der erste Parameter von
length_global
, alsself
Parameter in wiederverwendet werden kannlength_new
. Dies wäre ohne eine explizite nicht möglichself
.Eine andere Möglichkeit, die Notwendigkeit des Expliziten
self
zu verstehen, besteht darin, zu sehen, wo Python syntaktischen Zucker hinzufügt. Wenn Sie daran denken, dass im Grunde ein Anruf wiewird intern umgewandelt in
Es ist leicht zu erkennen, wo das
self
passt. Sie schreiben keine Instanzmethoden in Python. Was Sie schreiben, sind Klassenmethoden, die eine Instanz als ersten Parameter verwenden müssen. Daher müssen Sie den Instanzparameter explizit irgendwo platzieren.quelle
Vector.length_new = length_global
zeigt.Angenommen, Sie haben eine Klasse,
ClassA
die eine Methode enthält,methodA
die wie folgt definiert ist:und
ObjectA
ist eine Instanz dieser Klasse.Wenn
ObjectA.methodA(arg1, arg2)
es jetzt aufgerufen wird, konvertiert Python es intern für Sie als:Die
self
Variable bezieht sich auf das Objekt selbst.quelle
Wenn Objekte instanziiert werden, wird das Objekt selbst an den Parameter self übergeben.
Aus diesem Grund sind die Daten des Objekts an das Objekt gebunden. Im Folgenden finden Sie ein Beispiel dafür, wie Sie die Daten der einzelnen Objekte visualisieren möchten. Beachten Sie, wie 'self' durch den Objektnamen ersetzt wird. Ich sage nicht, dass dieses Beispieldiagramm unten völlig genau ist, aber es dient hoffentlich einem Zweck bei der Visualisierung des Gebrauchs des Selbst.
Das Objekt wird an den Parameter self übergeben, damit das Objekt seine eigenen Daten behalten kann.
Obwohl dies möglicherweise nicht ganz korrekt ist, denken Sie an den Prozess des Instanziierens eines Objekts wie folgt: Wenn ein Objekt erstellt wird, verwendet es die Klasse als Vorlage für seine eigenen Daten und Methoden. Ohne einen eigenen Namen an den Parameter self zu übergeben, bleiben die Attribute und Methoden in der Klasse als allgemeine Vorlage erhalten und werden nicht auf das Objekt verwiesen (zu diesem gehören). Wenn Sie also den Namen des Objekts an den Parameter self übergeben, bedeutet dies, dass 100 Objekte, die aus einer Klasse instanziiert wurden, alle ihre eigenen Daten und Methoden verfolgen können.
Siehe die Abbildung unten:
quelle
Ich mag dieses Beispiel:
quelle
self
Variablentyp ab, sondern auch vom Variablentyp. Versuchen Sie, das erste Beispiel mit einer einfachen Ganzzahl anstelle einer Liste zu erstellen. Das Ergebnis wäre ganz anders.a.foo
im ersten Beispiel sagen dürfen und nichtA.foo
? Gehört eindeutigfoo
zur Klasse ...a
undb
beide Bezeichnungen (oder Zeiger) fürA()
(die Klasse) sind.a.foo
verweist auf dieA().foo
Klassenmethode. Im zweiten Beispiela
wird jedoch eine Referenz auf eine Instanz vonA()
, wie dies der Fall istb
. Jetzt, da es sich um Instanzen anstelle des Klassenobjekts selbst handelt, ermöglicht self derfoo
Methode, die Instanzen zu bearbeiten.Ich werde mit Code demonstrieren, der keine Klassen verwendet :
Klassen sind nur eine Möglichkeit, um zu vermeiden, dass dieser "Status" ständig übergeben wird (und andere nette Dinge wie Initialisierung, Klassenzusammensetzung, die selten benötigten Metaklassen und die Unterstützung benutzerdefinierter Methoden zum Überschreiben von Operatoren).
Lassen Sie uns nun den obigen Code mithilfe der integrierten Python-Klassenmaschinerie demonstrieren, um zu zeigen, wie es im Grunde dasselbe ist.
[hat meine Antwort von einer doppelten geschlossenen Frage migriert]
quelle
Die folgenden Auszüge stammen aus der Python-Dokumentation zu self :
Weitere Informationen finden Sie im Python-Dokumentations-Tutorial zu Klassen .
quelle
Neben allen anderen bereits genannten Gründen ermöglicht es einen einfacheren Zugriff auf überschriebene Methoden. Sie können anrufen
Class.some_method(inst)
.Ein Beispiel dafür, wo es nützlich ist:
quelle
Die Verwendung ähnelt der Verwendung des
this
Schlüsselworts in Java, dh um einen Verweis auf das aktuelle Objekt zu geben.quelle
Python ist im Gegensatz zu Java oder C ++ keine Sprache für objektorientierte Programmierung.
Wenn man eine statische Methode in Python aufruft, schreibt man einfach eine Methode mit regulären Argumenten.
Für eine Objektmethode, bei der Sie eine Variable erstellen müssen, bei der es sich in diesem Fall um ein Tier handelt, ist jedoch das Argument self erforderlich
Die self-Methode wird auch verwendet, um auf ein Variablenfeld innerhalb der Klasse zu verweisen.
In diesem Fall bezieht sich self auf die Variable animalName der gesamten Klasse. ERINNERN SIE SICH: Wenn Sie eine Variable in einer Methode haben, funktioniert self nicht. Diese Variable ist einfach nur vorhanden, während diese Methode ausgeführt wird. Um Felder (die Variablen der gesamten Klasse) zu definieren, müssen Sie sie AUSSERHALB der Klassenmethoden definieren.
Wenn Sie kein einziges Wort von dem verstehen, was ich sage, dann Google "Objektorientierte Programmierung". Sobald Sie dies verstanden haben, müssen Sie diese Frage nicht einmal mehr stellen :).
quelle
staticMethod()
undobjectMethod(self)
. Ich möchte hinzufügen, dass, um die erste aufzurufen, Sie sagen würdenAnimal.staticMethod()
, währendobjectMethod()
eine Instanz benötigt:a = Animal(); a.objectMethod()
def getAnimalName
Um die Zeichenfolge, die Sie zurückgeben möchten, nicht zu beschädigen,self
bezieht sie sich auf die Instanz der Klasse und nicht auf ein Feld darin.Es ist da, um dem Python-Zen zu folgen: "Explizit ist besser als implizit". Es ist in der Tat ein Verweis auf Ihr Klassenobjekt. In Java und PHP heißt es beispielsweise
this
.Wenn
user_type_name
sich in Ihrem Modell ein Feld befindet, greifen Sie über zuself.user_type_name
.quelle
Zuallererst ist Selbst ein herkömmlicher Name, man könnte alles andere (kohärent sein) an seine Stelle setzen.
Es bezieht sich auf das Objekt selbst. Wenn Sie es also verwenden, erklären Sie, dass .name und .age Eigenschaften der Student-Objekte (Hinweis, nicht der Student-Klasse) sind, die Sie erstellen möchten.
Code ist hier
quelle
self
ist eine Objektreferenz auf das Objekt selbst, daher sind sie gleich. Python-Methoden werden nicht im Kontext des Objekts selbst aufgerufen.self
in Python kann verwendet werden, um mit benutzerdefinierten Objektmodellen oder etwas anderem umzugehen.quelle
Die Verwendung des Arguments, herkömmlich genannt
self
ist nicht so schwer zu verstehen, wie auch, warum es notwendig ist? Oder warum es explizit erwähnen? Ich nehme an, das ist eine größere Frage für die meisten Benutzer, die diese Frage nachschlagen, oder wenn dies nicht der Fall ist, werden sie mit Sicherheit die gleiche Frage haben, wenn sie Python lernen. Ich empfehle ihnen, diese paar Blogs zu lesen:1: Verwendung von selbsterklärten
Beachten Sie, dass es sich nicht um ein Schlüsselwort handelt.
2: Warum haben wir es so und warum können wir es nicht wie Java als Argument entfernen und stattdessen ein Schlüsselwort haben
Eine andere Sache, die ich hinzufügen möchte, ist,
self
dass ich mit einem optionalen Argument statische Methoden innerhalb einer Klasse deklarieren kann, indem ich nicht schreibeself
.Codebeispiele:
PS : Dies funktioniert nur in Python 3.x.
In früheren Versionen müssen Sie den
@staticmethod
Dekorator explizit hinzufügen , andernfalls ist einself
Argument obligatorisch.quelle
Ich bin überrascht, dass niemand Lua erzogen hat. Lua verwendet auch die Variable 'self', sie kann jedoch weggelassen, aber weiterhin verwendet werden. C ++ macht dasselbe mit 'this'. Ich sehe keinen Grund, in jeder Funktion 'self' deklarieren zu müssen, aber Sie sollten es trotzdem genauso verwenden können wie mit lua und C ++. Für eine Sprache, die stolz darauf ist, kurz zu sein, ist es seltsam, dass Sie die Selbstvariable deklarieren müssen.
quelle
Schauen Sie sich das folgende Beispiel an, das den Zweck von klar erklärt
self
self
wird verwendet / benötigt, um zwischen Instanzen zu unterscheiden.Quelle: Selbstvariable in Python erklärt - Pythontips
quelle
Denn weil Python übrigens so gestaltet ist, würden die Alternativen kaum funktionieren. Python wurde entwickelt, um die Definition von Methoden oder Funktionen in einem Kontext zu ermöglichen, in dem sowohl implizite
this
(a-la Java / C ++) als auch explizite@
(a-la Ruby) nicht funktionieren würden. Lassen Sie uns ein Beispiel mit dem expliziten Ansatz mit Python-Konventionen haben:Jetzt würde die
fubar
Funktion nicht funktionieren, da davon ausgegangen wird, dassself
es sich um eine globale Variable handelt (und auch infrob
). Die Alternative wäre, Methoden mit einem ersetzten globalen Bereich auszuführen (wobeiself
ist das Objekt).Der implizite Ansatz wäre
Dies würde bedeuten, dass
myX
dies als lokale Variable infubar
(und in) interpretiert wirdfrob
) . Die Alternative wäre hier, Methoden mit einem ersetzten lokalen Bereich auszuführen, der zwischen den Aufrufen beibehalten wird, aber dies würde die Möglichkeit lokaler Methodenvariablen aufheben.Die aktuelle Situation funktioniert jedoch gut:
Hier wird beim Aufrufen als Methode
frob
das Objekt empfangen, für das es über denself
Parameter aufgerufen wird, und esfubar
kann weiterhin mit einem Objekt als Parameter aufgerufen werden und funktioniert genauso (es ist dasselbe, wieC.frob
ich denke).quelle
In der
__init__
Methode bezieht sich self auf das neu erstellte Objekt. In anderen Klassenmethoden bezieht es sich auf die Instanz, deren Methode aufgerufen wurde.Selbst als Name ist nur eine Konvention , nennen Sie es wie Sie wollen! Wenn Sie es jedoch verwenden, um beispielsweise das Objekt zu löschen, müssen Sie denselben Namen verwenden :
__del__(var)
, wovar
in der__init__(var,[...])
Sie sollten auch einen Blick darauf werfen
cls
, um das Gesamtbild zu erhalten . Dieser Beitrag könnte hilfreich sein.quelle
self verhält sich wie der aktuelle Objektname oder die Instanz der Klasse.
quelle
self
ist unvermeidbar.Es war nur eine Frage sollte
self
implizit oder explizit sein.Guido van Rossum
löste diese Frage zu sagen,self
muss bleiben .Also wo
self
leben die?Wenn wir uns nur an die funktionale Programmierung halten würden, würden wir sie nicht brauchen
self
. Sobald wir die Python-OOP betreten , finden wirself
dort.Hier ist der typische Anwendungsfall
class C
mit der Methodem1
Dieses Programm gibt Folgendes aus:
So
self
hält die Speicheradresse des Klasseninstanz. Der Zweck vonself
wäre, die Referenz für beispielsweise Methoden zu halten und expliziten Zugriff auf diese Referenz zu haben.Beachten Sie, dass es drei verschiedene Arten von Klassenmethoden gibt:
quelle
aus den Dokumenten ,
davor das zugehörige Snippet,
x = MyClass()
quelle
Es ist ein expliziter Verweis auf das Klasseninstanzobjekt.
quelle