13

Zunächst einmal verstehe ich, wie im Allgemeinen ein Dekorateur arbeiten. Und ich weiß, @staticmethod Streifen aus dem Beispiel Argumente in der Signatur, so dassKann jemand erklären, wie der Quellcode von staticmethod in Python funktioniert

class C(object): 
    @staticmethod 
    def foo(): 
     print 'foo' 
C.foo //<function foo at 0x10efd4050> 
C().foo //<function foo at 0x10efd4050> 

gültig.

Allerdings verstehe ich nicht, wie der Quellcode von staticmethod dies möglich machen.

Es scheint mir, dass, wenn Methode Einwickeln foo in staticmethod, eine Instanz von staticmethod instanziert wird, dann einige Magie geschieht, C.foo() legit zu machen.

Also .. was passiert in diesen magie? Was hat staticmethod tun?

Ich bin mir der enormen Themen auf SO bezüglich staticmethods bewusst, aber keine von ihnen adressiert meine Zweifel. Aber vielleicht habe ich das magische Schlüsselwort nicht getroffen. Wenn ja, lass es mich bitte wissen.

Denn wer für staticmethod Quellcode suchen, finden Sie in https://hg.python.org/cpython/file/c6880edaf6f3/Objects/funcobject.c

Antwort

12

A staticmethod Objekt ein descriptor ist. Die fehlende Magie besteht darin, dass Python die Methode aufruft, wenn er auf das Objekt als Attribut einer Klasse oder Instanz zugreift.

Zugriff So das Objekt als C.foo Ergebnisse in Python, dass zu C.__dict__['foo'].__get__(None, C) übersetzen, während instance_of_C.footype(instace_of_C).__dict__['foo'].__get__(instance_of_C, type(instance_of_C)) wird.

Die staticmethod Objekt ist defined in C code, aber ein Äquivalent in Python wäre:

class staticmethod(object): 
    def __init__(self, callable): 
     self.f = callable 
    def __get__(self, obj, type=None): 
     return self.f 
    @property 
    def __func__(self): 
     return self.f 

wo self.f die ursprüngliche gewickelt Funktion ist.

All dies ist erforderlich, weil Funktionen selbst Deskriptoren sind; Es ist das Deskriptor-Protokoll, das Ihnen Methoden-Objekte gibt (siehe python bound and unbound method object für weitere Details). Da auch sie eine Methode haben, ohne ein staticmethod Objekt, das die Funktion umhüllt, erzeugt ein functionobj.__get__ Aufruf stattdessen ein Methodenobjekt und übergibt ein self Argument.

Es gibt auch eine classmethod, die das zweite Argument zur descriptor.__get__ verwendet eine Funktion der Klasse zu binden, und dann gibt es property Objekte, die direkt die Bindung in einen Funktionsaufruf übersetzen. Siehe How does the @property decorator work?.

+0

Ich habe den Quellcode von PyCharm IDE .. was ich habe keine Ahnung, ob es die echte Kopie ist ..Oops – user2829759

+0

@ user2829759: PyCharm kann nicht auf den eigentlichen Quellcode zugreifen (wie es kompiliert C-Code ist) so rekonstruiert ein Shim für Sie von der Inspektion des Objekts. –

+0

@martijinpieters Gibt es an, was im C-Code passiert? – user2829759