Ich habe in einer Reihe von Sprachen wie Java, Ruby, Haskell und Python programmiert. Aufgrund verschiedener Projekte, an denen ich arbeite, muss ich täglich zwischen vielen Sprachen wechseln. Das Problem ist nun, dass ich oft vergesse, self
als ersten Parameter in den Funktionsdefinitionen in Python zu schreiben. Dies gilt auch für das Aufrufen von Methoden für dasselbe Objekt.
Trotzdem bin ich ziemlich erstaunt über diesen Ansatz von Python. Grundsätzlich müssen wir mehr eingeben, um die Dinge zu erledigen. In Sprachen wie Java und Ruby werden Dinge einfach gemacht, indem automatisch auf die Variablen im aktuellen Objekt verwiesen wird.
Meine Frage ist, warum das self
notwendig ist? Ist es eine reine Stilwahl oder gibt es einen Grund, warum Python Sie nicht auslassen kann, self
wie Java und C ++ Sie weglassen this
?
Antworten:
1) Warum ist
self
ein expliziter Parameter in Methodensignaturen erforderlich?Weil Methoden Funktionen sind und
foo.bar(baz)
nur syntaktischer Zucker fürbar(foo, baz)
. Klassen sind nur Wörterbücher, in denen einige der Werte Funktionen sind. (Konstruktoren sind auch nur Funktionen, weshalb Python nicht benötigt wird.new
) Man kann sagen, dass Python deutlich macht, dass Objekte aus einfacheren Komponenten erstellt werden. Dies steht im Einklang mit der Philosophie "explizit ist besser als implizit".Im Gegensatz dazu sind Objekte in Java wirklich magisch und können nicht auf einfachere Komponenten in der Sprache reduziert werden. In Java (zumindest bis Java 8) ist eine Funktion immer eine Methode, die einem Objekt gehört, und diese Eigenschaft kann aufgrund der statischen Natur der Sprache nicht geändert werden. Daher gibt es keine Unklarheit darüber, worauf es sich
this
bezieht, daher ist es sinnvoll, es implizit definieren zu lassen.JavaScript ist ein Beispiel für eine Sprache, die implizit
this
wie Java ist, bei der Funktionen jedoch getrennt von Objekten wie in Python vorhanden sein können. Dies führt zu großer Verwirrung darüber, worauf esthis
ankommt, wenn Funktionen in verschiedenen Kontexten herumgereicht und aufgerufen werden. Viele denken instinktiv, dass siethis
sich auf eine intrinsische Eigenschaft der Funktion beziehen müssen, während sie tatsächlich nur durch die Art und Weise bestimmt wird, wie die Funktion aufgerufen wird. Ich glaube, dassthis
ein expliziter Parameter wie in Python dies viel weniger verwirrend machen würde.Einige andere Vorteile des expliziten
self
Parameters:Dekorateure sind nur Funktionen, die andere Funktionen einschließen. Da Methoden nur Funktionen sind, funktionieren Dekoratoren bei Methoden genauso gut. Wenn es eine Art implizites Selbst gäbe, würden Dekorateure nicht transparent an Methoden arbeiten.
Klassenmethoden und statische Methoden akzeptieren keinen Instanzparameter. Klassenmethoden verwenden eine Klasse als erstes Argument (normalerweise aufgerufen
cls
). Das expliziteself
oder diecls
Parameter machen viel klarer, was los ist und worauf Sie in der Methode zugreifen können.2) Warum müssen Instanzvariablen immer mit "qualifiziert werden
self.
?In Java müssen Sie Mitgliedsvariablen nicht "
this.
" voranstellen , in Pythonself.
ist jedoch immer " " erforderlich. Der Grund dafür ist, dass Python keine explizite Syntax zum Deklarieren von Variablen hat. Daher kann nicht festgestellt werden, obx = 7
eine neue lokale Variable deklariert oder einer Mitgliedsvariablen zugewiesen werden soll. Das Angebenself.
löst diese Mehrdeutigkeit.quelle
self.
, wie Java) ist grundsätzlich nicht mit den Gültigkeitsbereichsregeln kompatibel, und wenn Sie dort explizit sein müssen, macht es keinen Sinn mehr, implizit über den Parameter zu sein.Es gibt einen ziemlich einfachen Grund, warum AFAIK weder im Cross-Site-Duplikat noch hier wirklich angesprochen wurde: Python begann als prozedurale Sprache. Es basierte auf ABC, ebenfalls eine prozedurale Sprache.
Die Objektorientierung wurde später hinzugefügt, und als sie hinzugefügt wurde, wollte Guido van Rossum die minimal mögliche Anzahl von Funktionen hinzufügen, um das Design von Python einfach zu halten. Python hatte bereits
dict
s und Funktionen. Warum also der Sprache etwas völlig Neues hinzufügen, wenn ein Objekt einfachdict
aus Slots und eine Klasse einfachdict
aus Funktionen bestehen kann? Eine Methode kann als teilweise angewendete Funktion interpretiert werden, die über ein einzelnes unterschiedliches Argument schließt. Und genau so werden Methoden in Python implementiert: Sie sind es nicht. Sie sind nur Funktionen, die ein besonders unterschiedliches Argument erhalten.quelle
Hier sind meine Schlussfolgerungen, die auf den obigen Antworten basieren und die eigenen Streifzüge des Guido zu diesem Thema lesen :
Die große Idee
Funktionen sind die wichtigen Bausteine in Python (oder wir sollten den einzigen sagen), tatsächlich emulieren wir OOP mithilfe von Funktionen.
Da eine Klasse nichts anderes als ein Wörterbuch von Funktionen ist, können wir zur Laufzeit jede Funktion an jede Klasse anhängen. Grundsätzlich ist es aus diesem Grund, die Funktionen zur Laufzeit herumzuwerfen, können wir Dinge wie Monkey Patching machen . Hier der
self
Parameter, der den parametrischen Polymorphismus unterstützt.quelle