2012-04-30 24 views
21

Ich einmal gelesen (ich denke auf einer Seite von Microsoft), dass es eine gute Möglichkeit ist, statische Klassen zu verwenden, wenn Sie zwei oder mehr Instanzen einer Klasse nicht benötigen.Statische Klassen in Python

Ich schreibe ein Programm in Python. Ist es ein schlechter Stil, wenn ich @classmethod für jede Methode einer Klasse verwende?

Antwort

6

Nach meiner Erfahrung ist das Erstellen einer Klasse aus mehreren Gründen eine sehr gute Lösung. Eine besteht darin, dass Sie die Klasse als "normale" Klasse (vor allem mehr als nur eine Instanz) häufiger verwenden, als Sie vielleicht denken. Es ist auch eine vernünftige Stilwahl, um mit Klassen für alles zu bleiben; Dies kann es anderen erleichtern, die Ihren Code lesen/pflegen, besonders wenn sie sehr OO sind - sie werden sich mit Klassen wohl fühlen. Wie in anderen Antworten angemerkt, ist es auch sinnvoll, nur "nackte" Funktionen für die Implementierung zu verwenden. Vielleicht möchten Sie mit einer Klasse beginnen und es zu einem Singleton/Borg-Muster machen (viele Beispiele, wenn Sie für diese googlen); es gibt Ihnen die Flexibilität, die Klasse (wieder) zu verwenden, um andere Bedürfnisse zu erfüllen. Ich würde den Ansatz der "statischen Klasse" als nicht-konventionell und nicht-pythonisch empfehlen, was es schwieriger zu lesen und zu pflegen macht.

+7

Die meisten Ihrer Antwort, große Ausnahmen sind der zweite und der letzte Satz, ist nur diskutierbar (und ich stimme eher nicht zu) und neben dem Punkt. Ich würde sagen, dass wir den ganzen Fluff, wie gut der Unterricht ist, verbessern würden, was denkst du? – delnan

+0

Ich stimme dieser Antwort gleichzeitig zu und stimme ihr nicht zu. Ich kann also nicht entscheiden, ob ich den Knopf hoch oder runter drücke. Jedenfalls bin ich damit einverstanden, dass die Objekte den Code leichter lesbar und pfleglich machen. Ich bin anderer Meinung über die Verwendung des Singleton/Borg-Musters http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Singleton.html. Es ist nicht so, dass es ein schlechtes Muster ist; Die Verwendung statischer Methoden mit Klassenvariablen ist jedoch wesentlich einfacher zu verwalten und liest ein extrem kompliziertes Codeprojekt ein. Ja, das mag technisch nicht korrekt sein, aber Junior-Programmierer werden es Ihnen danken. –

27

Im Allgemeinen ist eine solche Verwendung besser, wenn Sie nur Funktionen in einem Modul verwenden, ohne eine Klasse.

+8

+1. Absolut keine Notwendigkeit, eine Klasse in Python zu erstellen, wenn Sie keine Daten kapseln. –

+1

Ich beginne manchmal mit nur Funktionen, aber dann, weil ich gerne kleine Funktionen schreiben, muss ich manchmal den gleichen Parameter zwischen 3 oder 4 von ihnen übergeben, an dem Punkt beginne ich, diesen Parameter einzukapseln. Ich muss dieses Rätsel noch lösen. Gedanken? – Leonid

+0

@Leonid Ich würde argumentieren, wenn Ihre Funktionen unabhängig sind, aber immer noch die Parameter zwischen ihnen wollen, nur diese Parameter übergeben. Wenn Sie feststellen, dass Sie viele Anrufe mit derselben Sammlung von Parametern haben, erstellen Sie vielleicht ein 'namedtuple' oder etwas, das Sie weitergeben können. Dinge in einer Klasse zu speichern, nur um sie nicht herumzureichen, ist sowieso eine schlechte Idee - es könnte zu Problemen führen. –

13

Es ist schrecklich Stil, es sei denn, Sie müssen tatsächlich auf die Klasse zugreifen.

Eine statische Methode [...] übersetzt nicht in eine Python-Klassenmethode. Oh sicher, es führt zu mehr oder weniger dem gleichen Effekt, aber das Ziel einer Klassenmethode ist eigentlich, etwas zu tun, was normalerweise nicht einmal möglich ist [...] (wie das Erben eines Nicht-Standardkonstruktors). Die idiomatische Übersetzung einer statischen [...] Methode ist normalerweise eine Funktion auf Modul-Ebene, keine Klassenmethode oder statische Methode.

source

6

Es gibt ein paar Ansätze, die Sie dafür nehmen könnte. Wie andere bereits erwähnt haben, könnten Sie einfach Funktionen auf Modulebene verwenden. In diesem Fall ist das Modul selbst der Namespace, der sie zusammenhält. Eine weitere Option, die nützlich sein kann, wenn Sie den Zustand verfolgen müssen, besteht darin, eine Klasse mit normalen Methoden (self) zu definieren und dann eine einzelne globale Instanz davon zu definieren und ihre Instanzmethoden in den Modulnamensraum zu kopieren. Dies ist der Ansatz, den das "zufällige" Standard-Bibliotheksmodul anwendet - werfen Sie einen Blick auf lib/python2.5/random.py in Ihrem Python-Verzeichnis. Am unteren Ende hat es so etwas wie diese:

# Create one instance, seeded from current time, and export its methods 
# as module-level functions. [...] 
_inst = Random() 
seed = _inst.seed 
random = _inst.random 
uniform = _inst.uniform 
... 

Oder Sie den grundlegenden Ansatz können Sie beschrieben (obwohl ich würde mit @staticmethod anstatt @classmethod in den meisten Fällen empfehlen).