Wenn Sie eine Methode für eine Klasse in Python definieren, sieht sie ungefähr so aus:
class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
In einigen anderen Sprachen, wie z. B. C #, haben Sie jedoch einen Verweis auf das Objekt, an das die Methode mit dem Schlüsselwort "this" gebunden ist, ohne es als Argument im Methodenprototyp zu deklarieren.
War dies eine absichtliche Entscheidung zum Sprachdesign in Python oder gibt es einige Implementierungsdetails, die die Übergabe von "self" als Argument erfordern?
self
auf Mitglieder zuzugreifen - stackoverflow.com/questions/910020/…Antworten:
Ich zitiere gerne Peters 'Zen of Python. "Explizit ist besser als implizit."
In Java und C ++ kann '
this.
' abgeleitet werden, außer wenn Sie Variablennamen haben, die das Ableiten unmöglich machen. Also braucht man es manchmal und manchmal nicht.Python entscheidet sich dafür, solche Dinge explizit zu machen, anstatt auf einer Regel zu basieren.
Da nichts impliziert oder angenommen wird, werden außerdem Teile der Implementierung verfügbar gemacht.
self.__class__
,self.__dict__
Und andere „interne“ Strukturen sind in nahe liegender Weise zur Verfügung.quelle
Es geht darum, den Unterschied zwischen Methoden und Funktionen zu minimieren. Sie können auf einfache Weise Methoden in Metaklassen generieren oder Methoden zur Laufzeit zu bereits vorhandenen Klassen hinzufügen.
z.B
Es erleichtert auch (soweit ich weiß) die Implementierung der Python-Laufzeit.
quelle
self
in der Funktionsdeklaration nicht erforderlich ist (wohlgemerkt, dies wirft möglicherweise Steine aus einem Glashaus, da JavaScript eine ziemlich kniffligethis
Bindungssemantik aufweist)Ich schlage vor, dass man Guido van Rossums Blog zu diesem Thema lesen sollte - Warum explizites Selbst bleiben muss .
quelle
Python zwingt Sie nicht dazu, "self" zu verwenden. Sie können ihm einen beliebigen Namen geben. Sie müssen sich nur daran erinnern, dass das erste Argument in einem Methodendefinitionsheader eine Referenz auf das Objekt ist.
quelle
@staticmethod
damit nicht.Außerdem können Sie dies tun: (Kurz gesagt, das Aufrufen
Outer(3).create_inner_class(4)().weird_sum_with_closure_scope(5)
gibt 12 zurück, dies jedoch auf die verrückteste Art und Weise.In Sprachen wie Java und C # ist dies natürlich schwerer vorstellbar. Indem Sie die Selbstreferenz explizit machen, können Sie durch diese Selbstreferenz auf jedes Objekt verweisen. Außerdem ist eine solche Art, zur Laufzeit mit Klassen zu spielen, in den statischeren Sprachen schwieriger - nicht, dass es notwendigerweise gut oder schlecht ist. Es ist nur so, dass das explizite Selbst all diese Verrücktheit existieren lässt.
Stellen Sie sich außerdem Folgendes vor: Wir möchten das Verhalten von Methoden anpassen (für die Profilerstellung oder für verrückte schwarze Magie). Dies kann uns zum Nachdenken bringen: Was wäre, wenn wir eine Klasse hätten,
Method
deren Verhalten wir überschreiben oder kontrollieren könnten?Nun hier ist es:
Und jetzt:
InnocentClass().magic_method()
wird sich wie erwartet verhalten. Die Methode wird mit deminnocent_self
Parameter anInnocentClass
und mitmagic_self
der MagicMethod-Instanz gebunden. Seltsam, oder? Es ist wie mit 2 Schlüsselwörternthis1
undthis2
in Sprachen wie Java und C #. Magie wie diese ermöglicht es Frameworks, Dinge zu tun, die sonst viel ausführlicher wären.Auch hier möchte ich die Ethik dieses Materials nicht kommentieren. Ich wollte nur Dinge zeigen, die ohne eine explizite Selbstreferenz schwieriger zu machen wären.
quelle
OuterClass.this
, um das 'Selbst' von der äußeren Klasse zu erhalten, aber Sie können es trotzdemthis
als Referenz für sich selbst verwenden. sehr ähnlich zu dem, was Sie hier in Python tun. Für mich war das nicht schwerer vorstellbar. Vielleicht hängt es von den Kenntnissen der betreffenden Sprache ab?Something
, die wiederum in einer weiteren anonymen Implementierung von definiert istSomething
? In Python können Sie sich natürlich auf jeden Bereich beziehen.this
. Implizite Referenzen sind in Java unmöglich.this
Ergebnis verweist . Zum BeispielObject self1 = this;
(verwenden Sie entweder Object oder etwas weniger Generisches). Dann, wenn Sie Zugriff auf die Variable in den höheren Bereichen haben, könnten Sie haben Zugang zuself1
,self2
...selfn
. Ich denke, diese sollten für endgültig erklärt werden oder so, aber es könnte funktionieren.Ich denke, der wahre Grund neben "The Zen of Python" ist, dass Funktionen in Python erstklassige Bürger sind.
Was sie im Wesentlichen zu einem Objekt macht. Das grundlegende Problem ist nun, wenn Ihre Funktionen auch Objekte sind, wie würden Sie im objektorientierten Paradigma Nachrichten an Objekte senden, wenn die Nachrichten selbst Objekte sind?
Sieht aus wie ein Hühnerei-Problem. Um dieses Paradoxon zu verringern, besteht die einzige Möglichkeit darin, entweder einen Ausführungskontext an Methoden zu übergeben oder ihn zu erkennen. Da Python jedoch verschachtelte Funktionen haben kann, ist dies nicht möglich, da sich der Ausführungskontext für innere Funktionen ändern würde.
Dies bedeutet, dass die einzig mögliche Lösung darin besteht, 'self' (den Kontext der Ausführung) explizit zu übergeben.
Ich glaube, es ist ein Implementierungsproblem, das der Zen viel später hatte.
quelle
Ich denke, das hat mit PEP 227 zu tun:
quelle
Wie in Python selbst erklärt , entmystifiziert
Anrufungen:
init () definiert drei Parameter, aber wir haben gerade zwei (6 und 8) übergeben. In ähnlicher Weise erfordert distance () eins, aber es wurden keine Argumente übergeben.
Warum beschwert sich Python nicht über diese Nichtübereinstimmung der Argumentnummer ?
quelle
Es gibt noch eine andere sehr einfache Antwort: Laut dem Zen von Python ist "explizit besser als implizit".
quelle