@classmethod vs. @staticmethod in Python

Lesezeit: 7 Minuten

Benutzeravatar von Daryl Spitzer
Daryl Spitzer

Was ist der Unterschied zwischen einer Funktion dekoriert mit @staticmethod und einer dekoriert mit @classmethod?

  • Statische Methoden sind aus Gründen der Sauberkeit manchmal besser als Funktionen auf Modulebene in Python. Mit einer Modulfunktion ist es einfacher, nur die benötigte Funktion zu importieren und unnötige “.” Syntax (ich sehe Sie Objective-C an). Klassenmethoden sind nützlicher, da sie in Kombination mit Polymorphismus verwendet werden können, um “Fabrikmuster” -Funktionen zu erstellen. denn Klassenmethoden erhalten die Klasse als impliziten Parameter.

    – Faust der Wut

    6. Dezember 2017 um 3:44 Uhr

  • tl;dr >> Im Vergleich zu normalen Methoden kann auf die statischen Methoden und Klassenmethoden auch über die Klasse zugegriffen werden, aber im Gegensatz zu Klassenmethoden sind statische Methoden durch Vererbung unveränderlich.

    – Mr. Unnormalized Posterior

    11. Juli 2018 um 15:02 Uhr


  • Verwandter Vortrag von Raymond Hettinger zum Thema: youtube.com/watch?v=HTLu2DFOdTg

    – muuuuh

    10. September 2018 um 9:35 Uhr

Benutzeravatar von Thomas Wouters
Thomas Wouters

EIN statische Methode ist eine Methode, die nichts über die Klasse oder Instanz weiß, für die sie aufgerufen wurde. Es erhält nur die übergebenen Argumente, kein implizites erstes Argument. In Python ist es im Grunde nutzlos – Sie können einfach eine Modulfunktion anstelle einer statischen Methode verwenden.

EIN Klassenmethode, andererseits ist eine Methode, die die Klasse, in der sie aufgerufen wurde, oder die Klasse der Instanz, in der sie aufgerufen wurde, als erstes Argument übergeben bekommt. Dies ist nützlich, wenn Sie möchten, dass die Methode eine Factory für die Klasse ist: Da sie die tatsächliche Klasse, für die sie aufgerufen wurde, als erstes Argument erhält, können Sie immer die richtige Klasse instanziieren, selbst wenn Unterklassen beteiligt sind. Beobachten Sie zum Beispiel, wie dict.fromkeys()eine Klassenmethode, gibt eine Instanz der Unterklasse zurück, wenn sie für eine Unterklasse aufgerufen wird:

>>> class DictSubclass(dict):
...     def __repr__(self):
...         return "DictSubclass"
... 
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>> 

  • Eine statische Methode ist nicht nutzlos – sie ist eine Möglichkeit, eine Funktion in eine Klasse einzufügen (weil sie logischerweise dorthin gehört), während sie anzeigt, dass sie keinen Zugriff auf die Klasse benötigt.

    – Toni Meyer

    26. September 2008 um 10:10 Uhr

  • Daher nur “im Grunde” unbrauchbar. Eine solche Organisation sowie Abhängigkeitsinjektion sind gültige Verwendungen statischer Methoden, aber da Module und nicht Klassen wie in Java die grundlegenden Elemente der Codeorganisation in Python sind, ist ihre Verwendung und Nützlichkeit selten.

    – Thomas Wouters

    26. September 2008 um 13:40 Uhr

  • Was ist logisch daran, eine Methode innerhalb einer Klasse zu definieren, wenn sie nichts mit der Klasse oder ihren Instanzen zu tun hat?

    – Ben James

    12. März 2010 um 9:11 Uhr


  • Vielleicht wegen der Erbschaft? Statische Methoden können genauso wie Instanzmethoden und Klassenmethoden vererbt und überschrieben werden, und die Suche funktioniert wie erwartet (anders als in Java). Statische Methoden werden nicht wirklich statisch aufgelöst, unabhängig davon, ob sie von der Klasse oder der Instanz aufgerufen werden, sodass der einzige Unterschied zwischen Klassen- und statischen Methoden das implizite erste Argument ist.

    – Haridsv

    8. April 2010 um 1:32 Uhr

  • Sie schaffen auch einen saubereren Namensraum und machen es einfacher zu verstehen, dass die Funktion etwas mit der Klasse zu tun hat.

    – Imbrondir

    22. August 2011 um 11:58 Uhr

Benutzeravatar von Du D
Du D.

Um zu entscheiden, ob Sie verwenden @statischeMethode oder @Klassenmethode Sie müssen in Ihre Methode schauen. Wenn Ihre Methode auf andere Variablen/Methoden in Ihrer Klasse zugreift, verwenden Sie @classmethod. Wenn Ihre Methode andererseits keine anderen Teile der Klasse berührt, verwenden Sie @staticmethod.

class Apple:

    _counter = 0

    @staticmethod
    def about_apple():
        print('Apple is good for you.')

        # note you can still access other member of the class
        # but you have to use the class instance 
        # which is not very nice, because you have repeat yourself
        # 
        # For example:
        # @staticmethod
        #    print('Number of apples have been juiced: %s' % Apple._counter)
        #
        # @classmethod
        #    print('Number of apples have been juiced: %s' % cls._counter)
        #
        #    @classmethod is especially useful when you move your function to another class,
        #       you don't have to rename the referenced class 

    @classmethod
    def make_apple_juice(cls, number_of_apples):
        print('Making juice:')
        for i in range(number_of_apples):
            cls._juice_this(i)

    @classmethod
    def _juice_this(cls, apple):
        print('Juicing apple %d...' % apple)
        cls._counter += 1

  • Was wäre der Vorteil von classmethod und cls._counter gegenüber staticmethod und Apple._counter

    – Robert Nowak

    11. Oktober 2019 um 10:38 Uhr

  • cls._counter wäre es noch cls._counter auch wenn der Code in eine andere Klasse gestellt oder der Klassenname geändert wird. Apple._counter ist spezifisch für die Apple Klasse; für eine andere Klasse oder wenn der Klassenname geändert wird, müssten Sie die referenzierte Klasse ändern.

    – apaderno

    12. November 2019 um 22:55 Uhr

Benutzeravatar von me_and
ich und

Offizielle Python-Dokumentation:

@Klassenmethode

Eine Klassenmethode erhält die Klasse als implizites erstes Argument, genauso wie eine Instanzmethode die Instanz erhält. Um eine Klassenmethode zu deklarieren, verwenden Sie dieses Idiom:

class C:
    @classmethod
    def f(cls, arg1, arg2, ...): ... 

Das @classmethod Form ist eine Funktion
Dekorateur – siehe die Beschreibung der Funktionsdefinitionen in Funktionsdefinitionen für Details.

Es kann entweder über die Klasse aufgerufen werden (wie z C.f()) oder auf einer Instanz (wie z C().f()). Die Instanz wird außer ihrer Klasse ignoriert. Wenn eine Klassenmethode für eine abgeleitete Klasse aufgerufen wird, wird das Objekt der abgeleiteten Klasse als implizites erstes Argument übergeben.

Klassenmethoden unterscheiden sich von statischen C++- oder Java-Methoden. Wenn Sie diese wollen, sehen Sie staticmethod() in diesem Abschnitt.

@statischeMethode

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, ...): ... 

Das @staticmethod Form ist eine Funktion
Dekorateur – siehe die Beschreibung der Funktionsdefinitionen in Funktionsdefinitionen für Details.

Es kann entweder über die Klasse aufgerufen werden (wie z C.f()) oder auf einer Instanz (wie z C().f()). Die Instanz wird außer ihrer Klasse ignoriert.

Statische Methoden in Python ähneln denen in Java oder C++. Für ein fortgeschritteneres Konzept siehe
classmethod() in diesem Abschnitt.

  • Was wäre der Vorteil von classmethod und cls._counter gegenüber staticmethod und Apple._counter

    – Robert Nowak

    11. Oktober 2019 um 10:38 Uhr

  • cls._counter wäre es noch cls._counter auch wenn der Code in eine andere Klasse gestellt oder der Klassenname geändert wird. Apple._counter ist spezifisch für die Apple Klasse; für eine andere Klasse oder wenn der Klassenname geändert wird, müssten Sie die referenzierte Klasse ändern.

    – apaderno

    12. November 2019 um 22:55 Uhr

Benutzeravatar der Community
Gemeinschaft

Hier ist ein kurzer Artikel zu dieser Frage

Die @staticmethod-Funktion ist nichts anderes als eine innerhalb einer Klasse definierte Funktion. Es ist aufrufbar, ohne zuerst die Klasse zu instanziieren. Seine Definition ist unveränderlich durch Vererbung.

Die @classmethod-Funktion kann auch aufgerufen werden, ohne die Klasse zu instanziieren, aber ihre Definition folgt der Unterklasse, nicht der Elternklasse, über Vererbung. Das liegt daran, dass das erste Argument für die Funktion @classmethod immer cls (Klasse) sein muss.

  • Bedeutet das also, dass ich durch die Verwendung einer statischen Methode immer an die übergeordnete Klasse gebunden bin und mit der Klassenmethode an die Klasse gebunden bin, in der ich die Klassenmethode deklariere (in diesem Fall die Unterklasse)?

    – Mohan Gulati

    3. November 2009 um 19:06 Uhr

  • Nein. Durch die Verwendung einer statischen Methode sind Sie überhaupt nicht gebunden; es gibt keinen impliziten ersten Parameter. Durch die Verwendung von classmethod erhalten Sie als impliziten ersten Parameter die Klasse, für die Sie die Methode aufgerufen haben (wenn Sie sie direkt für eine Klasse aufgerufen haben), oder die Klasse der Instanz, für die Sie die Methode aufgerufen haben (wenn Sie sie für eine Instanz aufgerufen haben).

    – Matt Anderson

    3. November 2009 um 19:18 Uhr

  • Könnte ein wenig erweitert werden, um zu zeigen, dass Klassenmethoden direkten Zugriff auf andere Klassenattribute und -methoden haben, wenn sie eine Klasse als erstes Argument haben, während statische Methoden dies nicht tun (dafür müssten sie MyClass.attr fest codieren).

    – MestreLion

    3. Mai 2012 um 10:01 Uhr


  • “Seine Definition ist unveränderlich durch Vererbung.” in Python keinen Sinn macht, können Sie eine statische Methode problemlos überschreiben.

    – cz

    17. September 2019 um 15:20 Uhr

1434320cookie-check@classmethod vs. @staticmethod in Python

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy