Bei der Integration einer Django App, die ich zuvor noch nicht verwendet habe, habe ich zwei verschiedene Methoden gefunden, um Funktionen in Klassen zu definieren. Der Autor scheint beide sehr absichtlich zu verwenden. Die erste ist eine, die ich selbst verwende viel:
class Dummy(object):
def some_function(self,*args,**kwargs):
do something here
self is the class instance
Der andere ist einer, den ich nicht benutze, hauptsächlich, weil ich nicht verstehe, wann ich ihn verwenden soll und wofür:
class Dummy(object):
@classmethod
def some_function(cls,*args,**kwargs):
do something here
cls refers to what?
In den Python docs wird der Dekorator classmethod
mit folgendem Satz erklärt:
Eine Klassenmethode empfängt die Klasse als implizites erstes Argument, genau wie eine Instanzmethode die Instanz empfängt.
Also denke ich, dass cls
auf Dummy
selbst verweist (das class
, nicht die Instanz). Ich verstehe nicht genau, warum das existiert, weil ich das immer tun könnte:
type(self).do_something_with_the_class
Ist das nur aus Gründen der Klarheit, oder habe ich den wichtigsten Teil übersehen: gruselige und faszinierende Dinge, die ohne sie nicht möglich wären?
Ihre Vermutung ist richtig - Sie verstehen , wie classmethod
s funktionieren.
Der Grund dafür ist, dass diese Methoden beide für eine Instanz OR für die Klasse) aufgerufen werden können (in beiden Fällen wird das Klassenobjekt als erstes Argument übergeben):
class Dummy(object):
@classmethod
def some_function(cls,*args,**kwargs):
print cls
#both of these will have exactly the same effect
Dummy.some_function()
Dummy().some_function()
Über die Verwendung dieser in Instanzen: Es gibt mindestens zwei Hauptverwendungen für den Aufruf einer Klassenmethode in einer Instanz:
self.some_function()
ruft die Version von some_function
für den tatsächlichen Typ von self
auf und nicht die Klasse, in der dieser Aufruf zufällig auftritt (und benötigt keine Beachtung, wenn der Klasse wird umbenannt); undsome_function
Erforderlich ist, um ein Protokoll zu implementieren, es jedoch nützlich ist, nur das Klassenobjekt aufzurufen.Der Unterschied zu staticmethod
: Es gibt eine andere Möglichkeit, Methoden zu definieren, die nicht auf Instanzdaten zugreifen, und zwar staticmethod
. Das schafft eine Methode, die überhaupt kein implizites erstes Argument erhält; Dementsprechend werden keine Informationen über die Instanz oder Klasse weitergegeben, für die sie aufgerufen wurden.
In [6]: class Foo(object): some_static = staticmethod(lambda x: x+1)
In [7]: Foo.some_static(1)
Out[7]: 2
In [8]: Foo().some_static(1)
Out[8]: 2
In [9]: class Bar(Foo): some_static = staticmethod(lambda x: x*2)
In [10]: Bar.some_static(1)
Out[10]: 2
In [11]: Bar().some_static(1)
Out[11]: 2
Die Hauptverwendung, die ich dafür gefunden habe, besteht darin, eine vorhandene Funktion (die kein self
erwartet) so anzupassen, dass sie eine Methode für eine Klasse (oder ein Objekt) ist.