Ist es möglich, statische Methoden in Python zu haben, die ich aufrufen könnte, ohne eine Klasse zu initialisieren, wie:
ClassName.static_method()
Ist es möglich, statische Methoden in Python zu haben, die ich aufrufen könnte, ohne eine Klasse zu initialisieren, wie:
ClassName.static_method()
Ja, mit dem staticmethod Tapezierer
class MyClass(object):
@staticmethod
def the_static_method(x):
print(x)
MyClass.the_static_method(2) # outputs 2
Beachten Sie, dass einige Codes die alte Methode der Definition einer statischen Methode verwenden können, indem sie staticmethod
als Funktion und nicht als Dekorator. Dies sollte nur verwendet werden, wenn Sie alte Versionen von Python unterstützen müssen (2.2 und 2.3)
class MyClass(object):
def the_static_method(x):
print(x)
the_static_method = staticmethod(the_static_method)
MyClass.the_static_method(2) # outputs 2
Dies ist völlig identisch mit dem ersten Beispiel (mit @staticmethod
), nur nicht mit der schönen Dekorator-Syntax
Schließlich verwenden Sie staticmethod
sparsam! Es gibt nur sehr wenige Situationen, in denen statische Methoden in Python notwendig sind, und ich habe sie schon oft dort eingesetzt gesehen, wo eine separate "Top-Level"-Funktion klarer gewesen wäre.
Der folgende Text ist ein Auszug aus der Dokumentation: :
Eine statische Methode erhält kein implizites erstes Argument. Um eine statische Methode zu deklarieren, verwenden Sie dieses Idiom:
class C: @staticmethod def f(arg1, arg2, ...): ...
Die @staticmethod-Form ist eine Funktion Tapezierer - siehe die Beschreibung der Funktionsdefinitionen in Funktionsdefinitionen für Einzelheiten.
Sie kann entweder in der Klasse aufgerufen werden (z. B.
C.f()
) oder auf eine Instanz (z. B.C().f()
). Die Instanz wird mit Ausnahme ihrer Klasse ignoriert.Statische Methoden in Python sind denen in Java oder C++ ähnlich. Für ein fortgeschritteneres Konzept siehe
classmethod()
.Weitere Informationen zu statischen Methoden finden Sie in der Dokumentation zur Standardtyphierarchie in Die Standard-Typenhierarchie .
Neu in Version 2.2.
Geändert in Version 2.4: Funktionsdekorator-Syntax hinzugefügt.
Warum das Hinzufügen @staticmethod
Dekoration oder die Verwendung eines Funktionszeigers, wenn man den ersten Schritt einfach vermeiden kann self
Parameter? Nun, für ein Objekt a
werden Sie nicht anrufen können a.your_static_method()
was in anderen Sprachen erlaubt ist, aber trotzdem als schlechte Praxis angesehen wird und der Compiler immer davor warnt
Ich verwende Python 2.7.12, mit @staticmethod decorator bin ich nicht in der Lage, die erste definierte statische Methode aufzurufen. Es gibt einen Fehler: TypeError: Das Objekt 'staticmethod' ist nicht aufrufbar
Supratim Samantray, sind Sie sicher? aquí Es ist eindeutig festgelegt, dass es nach 2.4 verwendet werden kann.
Ich denke, dass Steven hat tatsächlich Recht . Um die ursprüngliche Frage zu beantworten: Um eine Klassenmethode einzurichten, gehen Sie einfach davon aus, dass das erste Argument keine aufrufende Instanz sein wird, und stellen Sie dann sicher, dass Sie die Methode nur von der Klasse aus aufrufen.
(Beachten Sie, dass sich diese Antwort auf Python 3.x bezieht. In Python 2.x erhalten Sie eine TypeError
für den Aufruf der Methode in der Klasse selbst).
Zum Beispiel:
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
def rollCall(n): #this is implicitly a class method (see comments below)
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
In diesem Code geht die Methode "rollCall" davon aus, dass das erste Argument keine Instanz ist (wie es der Fall wäre, wenn sie von einer Instanz statt von einer Klasse aufgerufen würde). Solange "rollCall" von der Klasse und nicht von einer Instanz aufgerufen wird, funktioniert der Code einwandfrei. Wenn wir versuchen, "rollCall" von einer Instanz aus aufzurufen, z. B.:
rex.rollCall(-1)
würde jedoch eine Ausnahme ausgelöst werden, da zwei Argumente gesendet würden: sich selbst und -1, und "rollCall" ist nur für ein Argument definiert.
Übrigens würde rex.rollCall() die richtige Anzahl von Argumenten senden, aber auch eine Ausnahme auslösen, weil n jetzt eine Hundeinstanz (d.h. rex) darstellen würde, obwohl die Funktion erwartet, dass n numerisch ist.
Hier kommt die Dekoration ins Spiel: Wenn wir der Methode "rollCall" vorangestellt haben
@staticmethod
dann können wir sie sogar von einer Instanz aus aufrufen, indem wir ausdrücklich angeben, dass die Methode statisch ist. Jetzt,
rex.rollCall(-1)
funktionieren würde. Das Einfügen von @staticmethod vor einer Methodendefinition verhindert also, dass eine Instanz sich selbst als Argument sendet.
Sie können dies überprüfen, indem Sie den folgenden Code mit und ohne die auskommentierte @staticmethod-Zeile ausprobieren.
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
@staticmethod
def rollCall(n):
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
rex.rollCall(-1)
Das erste Beispiel (Aufruf durch Klasse ohne @staticmethod) funktioniert bei mir unter Python 2.7 nicht. Ich erhalte "TypeError: unbound method rollCall() must be called with Dog instance as first argument (got int instance instead)".
Das funktioniert nicht. Sowohl Dog.rollCall(-1) als auch rex.rollCall(-1) geben das gleiche zurück TypeError: unbound method rollCall() must be called with Dog instance as first argument (got int instance instead)
@MestreLion Ich glaube nicht, dass dies ein großer Vorteil ist, da es nur statische und Instanzmethoden durcheinander bringt und das eine wie das andere aussehen lässt. Wenn man weiß, dass eine Methode statisch ist, sollte man sie als statische Methode aufrufen. Die Tatsache, dass die Methode Ihre Instanz nicht benötigt oder verwendet, sollte selbstverständlich sein, wo immer Sie die Methode verwenden. Ich verwende immer T.my_static_method()
o type(my_t_instance).my_static_method()
, da dies klarer ist und sofort deutlich macht, dass ich eine statische Methode aufrufe.
Ja, sehen Sie sich die staticmethod Dekorateur:
>>> class C:
... @staticmethod
... def hello():
... print "Hello World"
...
>>> C.hello()
Hello World
Sie müssen nicht unbedingt die @staticmethod
Dekorateur. Man deklariert einfach eine Methode (die nicht den Parameter self erwartet) und ruft sie von der Klasse aus auf. Der Dekorator ist nur für den Fall da, dass Sie die Methode auch von einer Instanz aus aufrufen wollen (was Sie nicht wollten)
Meistens verwendet man aber nur Funktionen...
Dies würde nicht für Python 2.5.2 funktionieren class Dummy: def static1(): print "hello from static1" @staticmethod def static2(): print "hello from static2" Dummy.static2() Dummy.static1()
Ausgabe: hallo von static2 Traceback<letzter Aufruf>: File "ll.py", line 46, in <module> Dummy.static1() TypeError: unbound method static1() must be called with Dummy instance as first argument (got nothing instead)
Dies funktioniert nicht innerhalb einer Klasse. Python übergibt self
als erstes Argument, es sei denn, Sie weisen es an, dies nicht zu tun. (siehe: decorator)
Eigentlich ist dies in 2.7 falsch und ab 3.X legal (in 3.2 gut getestet). Das heißt, Sie kann nicht eine Methode aus dem Kontext einer Klasse ohne den @staticmethod Dekorator in 2.7 und darunter aufrufen. In 3.2 funktioniert es und fügt eine self
je nach Aufforderung entsprechend. Testfall: pastebin.com/12DDV7DB .
Statische Methoden in Python?
Ist es möglich, statische Methoden in Python zu haben, so dass ich sie aufrufen kann ohne eine Klasse zu initialisieren, wie:
ClassName.StaticMethod()
Ja, statische Methoden können auf diese Weise erstellt werden (obwohl es ein bisschen mehr Pythonisch Unterstriche anstelle von CamelCase für Methoden zu verwenden):
class ClassName(object):
@staticmethod
def static_method(kwarg1=None):
'''return a value that is a function of kwarg1'''
Das obige Beispiel verwendet die Dekorator-Syntax. Diese Syntax ist äquivalent zu
class ClassName(object):
def static_method(kwarg1=None):
'''return a value that is a function of kwarg1'''
static_method = staticmethod(static_method)
Dies kann genau so verwendet werden, wie Sie es beschrieben haben:
ClassName.static_method()
Ein eingebautes Beispiel für eine statische Methode ist str.maketrans()
in Python 3, die eine Funktion in der string
Modul in Python 2.
Eine weitere Option, die wie von Ihnen beschrieben verwendet werden kann, ist die classmethod
Der Unterschied besteht darin, dass die Klassenmethode die Klasse als implizites erstes Argument erhält, und wenn sie unterklassig ist, erhält sie die Unterklasse als implizites erstes Argument.
class ClassName(object):
@classmethod
def class_method(cls, kwarg1=None):
'''return a value that is a function of the class and kwarg1'''
Beachten Sie, dass cls
ist kein erforderlicher Name für das erste Argument, aber die meisten erfahrenen Python-Programmierer werden es für schlecht gemacht halten, wenn Sie etwas anderes verwenden.
Diese werden in der Regel als alternative Konstrukteure verwendet.
new_instance = ClassName.class_method()
Ein eingebautes Beispiel ist dict.fromkeys()
:
new_dict = dict.fromkeys(['key1', 'key2'])
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.