Vielleicht hilft ein Beispielcode etwas: Beachten Sie den Unterschied in den Aufrufsignaturen von foo
, class_foo
und static_foo
:
class A(object):
def foo(self, x):
print(f"Ausführen von foo({self}, {x})")
@classmethod
def class_foo(cls, x):
print(f"Ausführen von class_foo({cls}, {x})")
@staticmethod
def static_foo(x):
print(f"Ausführen von static_foo({x})")
a = A()
Im Folgenden wird die übliche Art dargestellt, wie eine Objektinstanz eine Methode aufruft. Die Objektinstanz a
wird implizit als erstes Argument übergeben.
a.foo(1)
# Ausführen von foo(<__main__.A object at 0xb7dbef0c>, 1)
Mit Klassenmethoden wird die Klasse der Objektinstanz implizit als erstes Argument übergeben, anstelle von self
.
a.class_foo(1)
# Ausführen von class_foo(, 1)
Sie können auch class_foo
mit der Klasse aufrufen. Tatsächlich, wenn Sie etwas als Klassenmethode definieren, ist es wahrscheinlich, weil Sie beabsichtigen, sie von der Klasse anstelle einer Klasseninstanz aufzurufen. A.foo(1)
hätte einen TypeError ausgelöst, aber A.class_foo(1)
funktioniert einwandfrei:
A.class_foo(1)
# Ausführen von class_foo(, 1)
Eine Verwendung von Klassenmethoden ist die Erstellung von erblichen alternativen Konstruktoren.
Mit Statischen Methoden wird weder self
(die Objektinstanz) noch cls
(die Klasse) implizit als erstes Argument übergeben. Sie verhalten sich wie normale Funktionen, außer dass Sie sie von einer Instanz oder von der Klasse aus aufrufen können:
a.static_foo(1)
# Ausführen von static_foo(1)
A.static_foo('hi')
# Ausführen von static_foo(hi)
Statische Methoden werden verwendet, um Funktionen, die eine logische Verbindung zu einer Klasse haben, zur Klasse zu gruppieren.
foo
ist nur eine Funktion, aber wenn Sie a.foo
aufrufen, erhalten Sie nicht nur die Funktion, sondern eine "teilweise angewendete" Version der Funktion, bei der die Objektinstanz a
als erstes Argument an die Funktion gebunden ist. foo
erwartet 2 Argumente, während a.foo
nur 1 Argument erwartet.
a
ist an foo
gebunden. Das ist damit gemeint, wenn unten von "gebunden" die Rede ist:
print(a.foo)
# >
Bei a.class_foo
ist a
nicht an class_foo
gebunden, sondern die Klasse A
ist an class_foo
gebunden.
print(a.class_foo)
# >
Hier wird auch bei einer statischen Methode, obwohl es sich um eine Methode handelt, a.static_foo
einfach eine gute alte Funktion ohne gebundene Argumente zurückgegeben. static_foo
erwartet 1 Argument und a.static_foo
erwartet auch 1 Argument.
print(a.static_foo)
#
Und natürlich geschieht dasselbe, wenn Sie static_foo
mit der Klasse A
aufrufen.
print(A.static_foo)
#
27 Stimmen
Statische Methoden sind manchmal als Funktionen auf Modulniveau in Python besser aufgehoben für die Sauberkeit. Mit einer Modulfunktion ist es einfacher, nur die Funktion zu importieren, die Sie benötigen und unnötige "."-Syntax zu vermeiden (ich sehe dich an, Objective-C). Klassenmethoden haben mehr Verwendung, da sie in Kombination mit Polymorphismus verwendet werden können, um Funktionen im "Factory Pattern" zu erstellen. Dies liegt daran, dass Klassenmethoden die Klasse als impliziten Parameter erhalten.
64 Stimmen
Tl;dr >> Im Vergleich zu normalen Methoden können statische Methoden und Klassenmethoden auch über die Klasse aufgerufen werden, aber im Gegensatz zu Klassenmethoden sind statische Methoden vererbungsfest.
9 Stimmen
Ähnlicher Vortrag von Raymond Hettinger zum Thema: youtube.com/watch?v=HTLu2DFOdTg
2 Stimmen
More precise youtube.com/watch?v=HTLu2DFOdTg&feature=youtu.be&t=2689 Sie benötigen nur Klassenmethode für alternative Konstruktoren. Andernfalls können Sie staticmethod verwenden und auf jedes Klassenattribut (über. / Dot) mit dem etwas informativeren tatsächlichen "Klassenname" anstelle von cls wie in classmethod zugreifen.