Kann jemand bitte erklären, warum es so ist?
class Foo:
def bar(self):
pass
a = Foo()
b = Foo()
a.bar == b.bar # False
a.bar is b.bar # False
Ich dachte, dass beide die Klassenmethode erben und es die einzige Methode ist.
Wenn Sie über eine in der Klasse definierte Instanz auf eine Funktion zugreifen, wird jedes Mal ein Objekt mit gebundener Methode erstellt. Aus den Dokumenten :
Was genau passiert, wenn eine Methode aufgerufen wird? Möglicherweise haben Sie bemerkt, dass dies
x.f()
ohne ein Argument oben aufgerufen wurde, obwohl die Funktionsdefinition fürf()
ein Argument angegeben hat. Was ist mit dem Streit passiert? Sicherlich löst Python eine Ausnahme aus, wenn eine Funktion, die ein Argument erfordert, ohne eine aufgerufen wird - auch wenn das Argument nicht tatsächlich verwendet wird ...Vielleicht haben Sie die Antwort erraten: Das Besondere an Methoden ist, dass das Instanzobjekt als erstes Argument der Funktion übergeben wird. In unserem Beispiel entspricht der Aufruf
x.f()
genauMyClass.f(x)
. Im Allgemeinen entspricht das Aufrufen einer Methode mit einer Liste von n Argumenten dem Aufrufen der entsprechenden Funktion mit einer Argumentliste, die durch Einfügen des Instanzobjekts der Methode vor dem ersten Argument erstellt wird.Wenn Sie immer noch nicht verstehen, wie Methoden funktionieren, kann ein Blick auf die Implementierung möglicherweise die Dinge klären. Wenn auf ein Instanzattribut verwiesen wird, das kein Datenattribut ist, wird seine Klasse durchsucht. Wenn der Name ein gültiges Klassenattribut angibt, das ein Funktionsobjekt ist, wird ein Methodenobjekt erstellt, indem das Instanzobjekt und das gerade gefundene Funktionsobjekt in einem abstrakten Objekt gepackt werden (Zeiger darauf): Dies ist das Methodenobjekt.
Beachten Sie, dass dies jedes Mal geschieht, wenn Sie auf eine Methode zugreifen :
>>> class Foo:
... def bar(self): pass
...
>>> f = Foo()
>>> f.bar is f.bar
False
Wie funktioniert das? Nun, eigentlich sind Funktionen Deskriptorobjekte . Beachten Sie das Vorhandensein von a __get__
:
>>> def func(): pass
...
>>> func.__get__
<method-wrapper '__get__' of function object at 0x101e38ae8>
Mit anderen Worten, Sie können sich Python-Funktionen so vorstellen, dass sie folgendermaßen implementiert sind:
class Function(object):
. . .
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
if obj is None:
return self
return types.MethodType(self, obj)
Natürlich sind sie nicht in Python implementiert (zumindest in CPython!).
Beachten Sie auch, dass der Zugriff auf die Funktion direkt in der Klasse dies natürlich nicht tut (zumindest in Python 3, das Sie in Ihrer Frage markiert haben):
>>> Foo.bar is Foo.bar
True
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen