@staticmethod vs module-level function

21

Hier geht es nicht um @staticmethodund @classmethod! Ich weiß wie es staticmethodfunktioniert. Was ich wissen möchte, sind die richtigen Anwendungsfälle für @staticmethodeine Funktion auf Modulebene.

Ich habe diese Frage gegoogelt, und es scheint eine allgemeine Übereinstimmung zu bestehen, dass Funktionen auf Modulebene statischen Methoden vorgezogen werden, da sie pythonischer sind. Statische Methoden haben den Vorteil, an ihre Klasse gebunden zu sein. Dies kann sinnvoll sein, wenn nur diese Klasse sie verwendet. In Python ist die Funktionalität jedoch in der Regel nach Modulen und nicht nach Klassen organisiert. Daher ist es in der Regel auch sinnvoll, sie zu Modulen zu machen.

Statische Methoden können auch von Unterklassen überschrieben werden. Dies ist je nach Ansicht ein Vorteil oder ein Nachteil. Obwohl statische Methoden in der Regel "funktional rein" sind, ist sie möglicherweise nicht intelligent, aber manchmal auch praktisch (obwohl dies eine der "praktischen, aber NIEMALS TUN" -Dingen ist, die nur die Erfahrung lehrt).

Gibt es allgemeine Faustregeln für die Verwendung von statischen Methoden oder Funktionen auf Modulebene? Welche konkreten Vor- oder Nachteile haben sie (zB zukünftige Erweiterung, externe Erweiterung, Lesbarkeit)? Geben Sie nach Möglichkeit auch ein Fallbeispiel an.

Darkfeline
quelle

Antworten:

11

Technisch gesehen verhalten sich eine statische Methode und eine Modulfunktion ziemlich identisch. In beiden Fällen funktionieren sie wie Standardfunktionen, wobei der Unterschied im Namespace liegt, in dem sie platziert sind. Die Entscheidung liegt also eher in der Wartbarkeit / Lesbarkeit.

Im Allgemeinen würde ich eine statische Methode verwenden, wenn einige oder alle dieser Kriterien erfüllt sind:

  • Es gibt bereits eine Klasse mit normalen Methoden
  • Die Funktion bezieht sich auf Objekte der Klasse im Allgemeinen, aber nicht auf eine bestimmte Instanz
  • Sie möchten die Methode so aufrufen können, als ob es sich um eine nicht statische Methode handelt, möglicherweise, weil Sie die Methode in Zukunft nicht statisch machen möchten, ohne den Clientcode zu beschädigen
Michael Slade
quelle
0

Ein Programm ist eine Simulation eines Stücks Realität. Auf diese Weise kommt es darauf an, wie Sie die Realität wahrnehmen.

Eine Funktion repräsentiert eine Aktivität. Je allgemeiner die Aktivität ist, desto größer ist die Tendenz, die Aktivität mit einer Funktion zu simulieren. Methoden sind an Klassen gebunden. Je spezifischer die Aktivität für die Klasse ist, desto eher wird sie von einer Methode simuliert.

Denken Sie an die trigonometrischen Funktionen. Sprich, das sin()ist so bekannt, dass man weiß, dass es zu Winkeln passt. Sie wissen, dass eine Gleitkommazahl als Eingabe gewünscht wird und der Gleitkommawert zurückgegeben wird. Auf jeden Fall kann es einen Winkeldatentyp geben, der durch eine Klasse dargestellt wird, und das .sin()Argument without kann eine normale Methode sein, die mit dem Winkelobjekt zusammenarbeitet, und .sin(x)mit einem einzelnen Argument kann es sich um eine statische Methode der Klasse handeln. Ich könnte wetten, dass mehr Leute denken, dass es besser ist, sin()eine einfache Funktion zu machen . Sie sind eher daran gewöhnt.

Ein anderer Gesichtspunkt : Ein Modul ähnelt einer Klasseninstanz. Es hat seine eigenen Mitgliedsvariablen und Mitgliedsfunktionen. In gewissem Sinne implementiert es ein Singleton-Muster. Immer wenn Sie es aus einem anderen Modul der Anwendung importieren, erhalten Sie Zugriff auf genau dieselben Variablen und Funktionen.

pepr
quelle
0

Ich habe eine Funktion, die einen Teil der tiefen Datenhierarchie eines Objekts als Argument verwendet. Es wäre umständlich, stattdessen die verschiedenen Argumente einzugeben, die zum Erreichen dieses Teils der Datenhierarchie erforderlich sind. Habe also keinen Grund, auf self oder cls zu verweisen. Die Funktionalität wird jedoch nur für Teile von Objekten einer bestimmten Klasse verwendet. Also scheint es mir eine Klassenmethode zu sein.

Außerdem ziehe ich es vor, den Klassennamen ('from module import class' anstatt 'import module') zu importieren. Das Einschließen der Funktion als statische Methode ermöglicht mir den Zugriff auf die Methode, während das Schreiben als Funktion auf Modulebene einen anderen Import erfordern würde.

DVD Avins
quelle
2
Wenn ich Sie wäre, würde ich es vermeiden, in der ersten Person zu antworten. Es ist verwirrend. Sie sollten stattdessen in der zweiten Person an den Fragesteller schreiben.
Aaron Hall
Vielleicht. Ich lieferte ein Anwendungsbeispiel, das möglicherweise mit den Vorstellungen des Fragestellers übereinstimmt oder nicht.
DVD Avins