Ich bin ein Java-Entwickler, der mit Python ein- und ausgeschaltet hat. Ich bin kürzlich auf diesen Artikel gestoßen, in dem häufige Fehler erwähnt werden, die Java-Programmierer machen, wenn sie Python lernen. Der erste fiel mir auf:
Eine statische Methode in Java wird nicht in eine Python-Klassenmethode übersetzt. Natürlich führt dies zu mehr oder weniger demselben Effekt, aber das Ziel einer Klassenmethode besteht darin, etwas zu tun, das in Java normalerweise nicht einmal möglich ist (wie das Erben eines nicht standardmäßigen Konstruktors). Die idiomatische Übersetzung einer statischen Java-Methode ist normalerweise eine Funktion auf Modulebene, keine Klassenmethode oder statische Methode. (Und statische Endfelder sollten in Konstanten auf Modulebene übersetzt werden.)
Dies ist kein großes Leistungsproblem, aber ein Python-Programmierer, der mit Java-Idiom-Code wie diesem arbeiten muss, wird durch die Eingabe von Foo.Foo.someMethod ziemlich irritiert, wenn es nur Foo.someFunction sein sollte. Beachten Sie jedoch, dass das Aufrufen einer Klassenmethode eine zusätzliche Speicherzuweisung beinhaltet, die beim Aufrufen einer statischen Methode oder Funktion nicht erfolgt.
Oh, und all diese Foo.Bar.Baz-Attributketten sind auch nicht kostenlos. In Java werden diese gepunkteten Namen vom Compiler nachgeschlagen, sodass es zur Laufzeit wirklich egal ist, wie viele davon Sie haben. In Python werden die Suchvorgänge zur Laufzeit ausgeführt, sodass jeder Punkt zählt. (Denken Sie daran, dass in Python "Flat ist besser als verschachtelt", obwohl es eher mit "Lesbarkeitszählungen" und "Einfach ist besser als komplex" zu tun hat, als mit Leistung.)
Ich fand das etwas seltsam, weil die Dokumentation für staticmethod lautet:
Statische Methoden in Python ähneln denen in Java oder C ++. Siehe auch classmethod () für eine Variante, die zum Erstellen alternativer Klassenkonstruktoren nützlich ist.
Noch rätselhafter ist, dass dieser Code:
class A:
def foo(x):
print(x)
A.foo(5)
Schlägt in Python 2.7.3 wie erwartet fehl, funktioniert aber in 3.2.3 einwandfrei (obwohl Sie die Methode nicht für eine Instanz von A aufrufen können, sondern nur für die Klasse.)
Es gibt also drei Möglichkeiten, statische Methoden zu implementieren (vier, wenn Sie mit der Klassenmethode zählen), jede mit subtilen Unterschieden, von denen eine scheinbar nicht dokumentiert ist. Dies scheint im Widerspruch zu Pythons Mantra zu stehen. Es sollte einen - und vorzugsweise nur einen - offensichtlichen Weg geben, dies zu tun. Welche Redewendung ist die pythonischste? Was sind die Vor- und Nachteile von jedem?
Folgendes verstehe ich bisher:
Modulfunktion:
- Vermeidet das Problem Foo.Foo.f ()
- Verschmutzt den Namespace des Moduls mehr als die Alternativen
- Keine Vererbung
statische Methode:
- Hält Funktionen, die sich auf die Klasse beziehen, innerhalb der Klasse und außerhalb des Modul-Namespace.
- Ermöglicht das Aufrufen der Funktion für Instanzen der Klasse.
- Unterklassen können die Methode überschreiben.
Klassenmethode:
- Identisch mit staticmethod, übergibt aber auch die Klasse als erstes Argument.
Normale Methode (nur Python 3) :
- Identisch mit staticmethod, kann die Methode jedoch nicht für Instanzen der Klasse aufrufen.
Überdenke ich das? Ist das kein Problem? Bitte helfen Sie!