Ich möchte dieses Verhalten von "unten" zu sehen.
Eine Funktion in Python fungiert als "descriptor object". Als solche hat es eine __get__()
Methode.
Ein Lesezugriff auf ein Klassenattribut, das eine solche __get__()
-Methode hat, wird auf diese Methode "umgeleitet". Ein Attributzugriff auf die Klasse wird als attribute.__get__(None, containing_class)
ausgeführt, während ein Attributzugriff auf die Instanz auf attribute.__get__(instance, containing_class)
abgebildet wird.
__get__()
Ein Verfahren Aufgabe der Funktion ist die Funktion in einem Verfahren, das Gegenstand einzuwickeln, die die Parameter self
wickelt weg - für den Fall eines Attributs Zugriff auf die Instanz. Dies wird als gebundene Methode bezeichnet.
Auf einem Klassenattribut Zugriff auf 2.x, ein __get__()
kehrt ein ungebundenes Methode Wrapper die Funktion, während, wie ich learned today, auf 3.x, es selbst zurückgibt. (Beachten Sie, dass der Mechanismus __get__()
in 3.x noch vorhanden ist, aber eine Funktion nur selbst zurückgibt.) Das ist fast das Gleiche, wenn man sich ansieht, wie es heißt, aber ein ungebundener Methodenwrapper prüft zusätzlich den korrekten Typ des self
Arguments.
Ein Aufruf staticmethod()
Aufruf erstellt nur ein Objekt, dessen __get__()
Aufruf entwickelt wurde, um das ursprünglich angegebene Objekt zurückzugeben, so dass es das beschriebene Verhalten rückgängig macht. Das ist, wie HYRY's trick Werke: das Attribut acces rückgängig macht die staticmethod()
Verpackung, der Anruf es wieder tut, so dass das „neue“ Attribut den gleichen Status wie die alten hat, obwohl in diesem Fall staticmethod()
scheint zweimal angewandt werden (aber wirklich isn‘ t).
(BTW: Es funktioniert auch in diesem seltsamen Zusammenhang.
s = staticmethod(8)
t = s.__get__(None, 2) # gives 8
obwohl 8
ist keine Funktion und 2
ist keine Klasse)
In Ihrer Frage, zwei Fälle:
cmd = Cmd.cmdOne
cmd() # works fine
greift auf die Klasse und fragt nach seinem cmdOne
Attribute, ein staticmethod()
Objekt. Dieser wird über seine __get__()
abgefragt und gibt die ursprüngliche Funktion zurück, die dann aufgerufen wird. Deshalb funktioniert es gut.
Cmd.cmd = Cmd.cmdOne
Cmd.cmd() # unbound error
macht das gleiche, aber ordnet dann diese Funktion zu Cmd.cmd
. Die nächste Zeile ist ein Attribut Zugriff - das tut, wieder, den __get__()
Aufruf die Funktion selbst und kehrt somit ein ungebundenes Verfahren, die mit einem korrekten self
Objekt als erstes Argument aufgerufen werden muss.
Beantwortet keine Frage. – martineau