Gilt es als Pythonic, mehrere Klassen in derselben Datei zu definieren?


31

Bei der ersten Arbeit mit Python habe ich festgestellt, dass ich am Ende mehrere Klassen in derselben Datei schreibe. Dies steht im Gegensatz zu anderen Sprachen wie Java, das eine Datei pro Klasse verwendet.

Normalerweise bestehen diese Klassen aus 1 abstrakten Basisklasse mit 1-2 konkreten Implementierungen, deren Verwendung geringfügig variiert. Ich habe unten eine solche Datei gepostet:

class Logger(object):

    def __init__(self, path, fileName):
        self.logFile = open(path + '/' + filename, 'w+')
        self.logFile.seek(0, 2)

    def log(self, stringtoLog):
        self.logFile.write(stringToLog)

    def __del__(self):
        self.logFile.close()

class TestLogger(Logger):   

    def __init__(self, serialNumber):
        Logger.__init__('/tests/ModuleName', serialNumber):

    def readStatusLine(self):
        self.logFile.seek(0,0)
        statusLine = self.logFile.readLine()
        self.logFile.seek(0,2)
        return StatusLine

    def modifyStatusLine(self, newStatusLine):
        self.logFile.seek(0,0)
        self.logFile.write(newStatusLine)
        self.logFile.seek(0,2)

class GenericLogger(Logger):

    def __init__(self, fileName):
        Logger.__init__('/tests/GPIO', fileName):

    def logGPIOError(self, errorCode):
        self.logFile.write(str(errorCode))

Wie oben gezeigt, habe ich eine Logger-Basisklasse mit ein paar Implementierungsunterschieden darunter.

Die Frage: Ist dieser Standard für Python oder für irgendeine Sprache? Welche Probleme können bei der Verwendung dieser Implementierung auftreten?

EDIT: Ich bin nicht wirklich auf der Suche nach Anleitungen zu dieser spezifischen Datei, sondern in einem allgemeineren Sinne. Was wäre, wenn die Klassen 3-5 mäßig komplexe Methoden wären? Wäre es dann sinnvoll, sie aufzuteilen? Wo ist die Grenze dafür, dass Sie eine Datei aufteilen sollten?


3
Es ist KEINE C ++ Sache, sich auf eine Klasse pro Datei zu beschränken. Java ist die einzige Sprache, die ich kenne. In C ++ ist es äußerst verbreitet, dass eine einzelne .h / .cpp-Datei eine Primärklasse und viele Hilfsklassen enthält, die für die Primärklasse privat sein können oder nicht.
Gort the Robot

@StevenBurnap Ich habe C ++ als Beispiel entfernt, da Sie richtig sind.
Ampt

1
Es ist auch in PHP gemacht, um das automatische Laden zu erleichtern. Auf der anderen Seite können Sie in PHP den Namespace explizit deklarieren.
Bodo

Antworten:


24

Das ist gut. Es ist auch in C ++ in Ordnung, als Referenz.

Eng gekoppelte Dinge zusammenzuhalten, ist eine vernünftige Praxis. Das Vermeiden einer unangemessenen Kopplung ist ebenfalls eine gute Praxis. Das richtige Gleichgewicht zu finden, ist keine Frage strenger Regeln, sondern ein Gleichgewicht zwischen verschiedenen Anliegen.

Einige Faustregeln:

  1. Größe

    Zu große Dateien können hässlich sein, aber das ist hier kaum der Fall. Hässlichkeit ist wahrscheinlich ein guter Grund, um eine Datei zu teilen, aber die Entwicklung dieses ästhetischen Sinns ist größtenteils eine Frage der Erfahrung. Daher hilft es Ihnen nicht, herauszufinden, was Sie a priori tun müssen

  2. Trennung von Bedenken

    Wenn Ihre konkreten Implementierungen sehr unterschiedliche interne Probleme haben, werden alle diese Probleme in einer einzigen Datei zusammengefasst. Beispielsweise machen Implementierungen mit nicht überlappenden Abhängigkeiten Ihre einzelne Datei von der Vereinigung all dieser Abhängigkeiten abhängig.

    Daher kann es manchmal sinnvoll sein, zu berücksichtigen, dass die Kopplung der Unterklassen an ihre Abhängigkeiten die Kopplung an die Schnittstelle überwiegt (oder umgekehrt, das Anliegen , eine Schnittstelle zu implementieren, schwächer ist als die internen Anliegen dieser Implementierung).

    Nehmen Sie als spezielles Beispiel eine generische Datenbankschnittstelle. Konkrete Implementierungen, die eine speicherinterne Datenbank, ein SQL-RDBMS bzw. eine Webabfrage verwenden, haben möglicherweise nichts gemeinsam, abgesehen von der Schnittstelle, und es ist unangenehm, alle zu zwingen, die kompakte speicherinterne Version auch zum Importieren einer SQL-Bibliothek zu verwenden.

  3. Verkapselung

    Obwohl Sie gut gekapselte Klassen in dasselbe Modul schreiben können , kann dies zu unnötiger Kopplung führen, nur weil Sie Zugriff auf Implementierungsdetails haben, die ansonsten nicht außerhalb des Moduls exportiert würden.

    Ich denke, dies ist nur ein schlechter Stil, aber Sie könnten eine bessere Disziplin durch Aufteilen des Moduls durchsetzen, wenn Sie die Gewohnheit wirklich nicht brechen können.


2
Ihre Antwort wäre aussagekräftiger, wenn Sie externe Referenzen zitieren würden, die die Normalität des Kombinierens von Klassen in einer Datei demonstrieren, oder wenn Sie eine ausführlichere Erläuterung geben würden, warum dies in Ordnung ist.

1
Ich habe die Frage bearbeitet, um darauf hinzuweisen, dass dies nur ein Beispiel für das ist, was ich meine, und nicht genau die Art der Frage darstellt. Warum ist es besser, sie in derselben Datei zu speichern, als sie bei Bedarf einfach zu importieren?
Ampt

Viele kleine Dateien zu haben, kann so schwierig sein wie ein paar große Dateien. Python ist eine ziemlich knappe Sprache. Ihr Beispiel zeigt dies. Diese drei Klassen stehen in direktem Zusammenhang und passen wahrscheinlich in ein einzelnes Editorfenster ohne Bildlauf.
Gort the Robot

1
@ GlenH7 - Ich bin mir nicht sicher, was die Referenzen angeht, da sie sich nur von meiner direkten Behauptung zu meiner Behauptung verschieben, dass meine Auswahlbias gültig ist. Ich habe stattdessen versucht, mich auf die Erklärung zu konzentrieren.
Nutzlos

7

Meine üblichen Referenzdokumente, um zu wissen, was Python ist.

Einfach ist besser als komplex.

Flach ist besser als verschachtelt.

Aus dem Zen von Python

Fast ausnahmslos verwenden Klassennamen die CapWords-Konvention.

Paket- und Modulnamen Module sollten kurze Namen in Kleinbuchstaben haben. [...] Modulnamen werden Dateinamen zugeordnet

Ab PEP 8

Meine Interpretation ist, dass es in Ordnung ist, da es die Dinge einfach und flach halten würde. Da Klassennamen und Dateinamen unterschiedliche Groß- und Kleinschreibung haben, sollten sie sowieso nicht identisch sein, sodass ich keine Probleme beim Packen mehrerer zusammengehöriger Klassen in eine Datei sehen würde.


7
Könnten Sie dies auf die für die Frage relevanten Teile reduzieren? Ich habe beide mehrfach gelesen, aber es fällt mir schwer, herauszufinden, welche Teile sich speziell auf meine aktuelle Frage beziehen.
Ampt

1
In der Tat habe ich meine Antwort bearbeitet.
SylvainD

1

Was Sie jetzt haben, ist in Ordnung. Durchsuchen Sie die Standardbibliothek - es gibt viele Module mit mehreren verwandten Klassen in einer einzigen Datei. Irgendwann werden die Dinge größer und Sie werden eventuell Module mit mehreren Dateien verwenden wollen, aber es gibt keine wirklichen Regeln, wann. Die Dinge werden nur aufgeteilt, wenn sich eine Datei zu groß anfühlt.


0

Es ist definitiv in Ordnung und ich würde Sie ermutigen, mehrere Klassen in einer Datei zu haben, solange sie realisiert sind. Im Allgemeinen sollten Ihre Klassen kurz und prägnant sein und Sie sollten das Verhalten lieber in zwei oder mehr Klassen aufteilen, als riesige monolithische Klassen zu bauen. Wenn Sie mehrere kleine Klassen schreiben, ist es wirklich notwendig und hilfreich, die verwandten Klassen in derselben Datei zu belassen.


-1

Kurz gesagt - verdammt ja.

Darüber hinaus ist es manchmal sehr praktisch, mehrere Klassen in einer einzigen Datei zu haben. Einige Pakete ( six, bottle) werden explizit in einer einzigen Datei ausgeliefert, um problemlos in Module von Drittanbietern integriert zu werden, ohne dass Pip installiert werden muss (manchmal wünschenswert). Stellen Sie jedoch sicher, dass Sie Ihren Code gut organisieren. Verwenden Sie intensiv Codekommentare und Trennungsblöcke, um die Lesbarkeit zu verbessern.


3
Dies scheint nichts Wesentliches zu der vorherigen Antwort hinzuzufügen, die vor einigen Jahren veröffentlicht wurde
Mücke
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.