Sinn und Zweck von staticmethod und classmethod

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
pudeldestodes
User
Beiträge: 65
Registriert: Samstag 9. Juni 2007, 23:45

Ich habe jetzt lange darüber "sinniert", was Sinn und Zweck von staticmethod und classmethod sein soll. Mit Hilfe von stackoverflow.com bin ich auf das Beispiel von dict.fromkeys gestoßen, das eine classmethod darstellt. Nach endlosem Auf-dem-Schlauch-stehen verstehe ich jetzt glaube ich auch, was dort gemeint ist. Der Sinn der Klassenmethode ist dort, dass ich eben dict.fromkeys schreiben kann (anstatt dict().foo() für eine Instanzmethode), also nur unter Nennung des Klassennamens eine Art alternativen Konstruktor aufrufe (und eben nicht auf einer Instanz der Klasse). Und verstehe ich das jetzt richtig, dass in diesem Falle dictfromkeys keine staticmethod sein könnte, denn dann wüsste sie nicht, was für ein Objekt sie im Falle von Vererbung zurückgeben soll?

Code: Alles auswählen

class DictSubclass(dict):
    pass

DictSubclass.fromkeys('abc')
Dort soll ja ein Wörterbuch vom Typ 'DictSubclass' erstellt werden - wäre fromkeys eine staticmethod, dann wäre das nicht möglich, da fromkeys nicht wüsste, auf welcher Klasse es aufgerufen wurde. Richtig?

Aber wozu braucht man denn dann eine staticmethod? In dem oben verlinkten Beitrag steht sie sei mehr oder weniger nutzlos. Aber warum gibt es sie denn dann, da muss doch zumindest irgendwo irgendein Vorteil vorhanden sein?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

staticmethod ist in der Tat i.d.R. nutzlos und den Zweck von classmethod hast du erfolgreich herausgefunden.
BlackJack

@pudeldestodes: `staticmethod`\s sind ja eigentlich keine Methoden sondern Funktionen die im Namensraum einer Klasse stecken. Das kann manchmal sinnvoll sein, wenn man eine Funktion hat, die zwar weder Zugriff auf ein Exemplar noch auf die Klasse selbst benötigt, aber thematisch dennoch sehr eng mit der Klasse verbunden ist.

Zum Beispiel wenn man mehrere Klassen in einem Modul hat und mehr als eine davon eine Hilfsfunktion mit dem gleichen Namen, aber unterschiedlicher Implementierung braucht. Wenn man die Funktionen auf Modulebene unterbringen will, müsste man sich in dem Fall ja unterschiedliche Namen ausdenken, damit man sie auseinanderhalten kann.

Das kommt allerdings in der Praxis tatsächlich sehr selten vor. Bei mir zumindest.
Benutzeravatar
Empi
User
Beiträge: 26
Registriert: Montag 29. März 2010, 14:05

Mit statischen Methoden kann man auf statische Variablen zugreifen :roll:
Stell dir vor du hast 100 Objekte vom Typ "Musikcd", die alle ein Attribut "Verkaufspreis" haben.
Jetzt möchtest du den Preis ändern.

Statisch: Eine Anpassung betrifft alle Objekte
Instanzmeth./Variable: Du musst im Quellcode sicherstellen, daß alle existierenden Objekte angepasst werden. Solltest du eines vergessen, hat du eine inkonsistente Menge

Wenn möglich sollte man auf den Einsatz von statischen Elementen verzichten, es gibt aber gute Anwendungsmöglichkeiten.
BlackJack

@Empi: Man kann auch über Klassen- und normale Methoden auf Klassenattribute zugreifen. Sogar von Funktionen oder gar Code auf Modulebene. Das ist nichts was an `staticmethod()`\s irgendwie was besonderes wäre.

Ich habe hier übrigens absichtlich das Wort statisch vermieden (soweit es denn ging), denn so etwas gibt es es in Python nicht. Was Du beschreibst sind Attribute auf der Klasse und die sind in Python genauso dynamisch wie Attribute auf beliebigen anderen Objekten.
Benutzeravatar
Empi
User
Beiträge: 26
Registriert: Montag 29. März 2010, 14:05

BlackJack hat geschrieben:@Empi: Man kann auch über Klassen- und normale Methoden auf Klassenattribute zugreifen. Sogar von Funktionen oder gar Code auf Modulebene. Das ist nichts was an `staticmethod()`\s irgendwie was besonderes wäre.

Ich habe hier übrigens absichtlich das Wort statisch vermieden (soweit es denn ging), denn so etwas gibt es es in Python nicht. Was Du beschreibst sind Attribute auf der Klasse und die sind in Python genauso dynamisch wie Attribute auf beliebigen anderen Objekten.
Das ist (mir) klar :D
Es ist einfach besserer Programmierstil (jetzt nicht hauen wollen - kann jeder besser finden was er will :roll:) wenn man die Klassenvariable mittels Klassenmethode anpasst.
Es stimmt schon, besser werden die Dinge Klassenmethode und Klassenattribut genannt (denn so heißen sie ja auch schließlich).
In meiner (Haupt-) Programmiersprache werden die Dinger halt mittels static deklariert, deswegen verfalle ich da oft in diese Ungenauigkeit.
pudeldestodes
User
Beiträge: 65
Registriert: Samstag 9. Juni 2007, 23:45

Danke für eure Erläuterungen, hat mir weitergeholfen :)
BlackJack

@Empi: In welcher Programmiersprache deklariert man Klassenmethoden mit `static`? Mir sind Klassenmethoden (`classmethod`\s) das erste mal bei Python über den Weg gelaufen. Ich kannte vorher nur `staticmethod`\s zum Beispiel von Java oder C#.

Und von wo man Klassenattribute nun verändert, ist nicht so sehr eine Stilfrage sondern was für eine Semantik man damit erreichen will. Die Stilfrage ist eher, ob man überhaupt veränderliche Klassenattribute möchte, denn das sind ja letztendlich nur ``global``\s in einer anderen Verkleidung.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Empi hat geschrieben:Es stimmt schon, besser werden die Dinge Klassenmethode und Klassenattribut genannt (denn so heißen sie ja auch schließlich).
In meiner (Haupt-) Programmiersprache werden die Dinger halt mittels static deklariert, deswegen verfalle ich da oft in diese Ungenauigkeit.
Das sind dann aber keine Klassenmethoden sondern statische Methoden. Klassenmethoden und statische Methoden sind zwei verschiedene Dinge. Der Unterschied zwischen klassen- und statischen Methoden ist, dass Klassenmethoden die Klasse übergeben bekommen und statische Methoden nicht, Klassenmethoden sind Instanzmethoden des Klassenobjekts. Statische Methoden sind normale Funktionen die innerhalb der Klassendefinition deklariert wurden. Eine statische Methode aus Java ist deswegen keine Klassenmethode.
Antworten