Est-il considéré comme Pythonic d'avoir plusieurs classes définies dans le même fichier?

31

En travaillant avec python pour la première fois, j'ai constaté que je finissais par écrire plusieurs classes dans le même fichier, ce qui est opposé à d'autres langages comme Java, qui utilise un fichier par classe.

Habituellement, ces classes sont composées d'une classe de base abstraite, avec 1-2 implémentations concrètes dont l'utilisation varie légèrement. J'ai posté un de ces fichiers ci-dessous:

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))

Comme vu ci-dessus, j'ai une classe de base Logger, avec quelques différences d'implémentation en dessous.

La question: est-ce standard pour python, ou pour n'importe quel langage? Quels problèmes pourraient survenir lors de l'utilisation de cette implémentation, le cas échéant?

EDIT: Je ne suis pas vraiment à la recherche de conseils sur ce dossier spécifique , mais dans un sens plus général. Et si les classes devenaient 3-5 méthodes modérément complexes? Serait-il logique de les séparer alors? Où est la limite pour dire que vous devez diviser un fichier?

Ampt
la source
3
Limiter à une classe par fichier n'est PAS une chose C ++. Java est le seul langage que je connaisse où il est considéré comme quelque chose à éviter. En C ++, il est extrêmement courant qu'un seul fichier .h / .cpp ait une classe principale et de nombreuses classes d'assistance, qui peuvent ou non être privées de la classe principale.
Gort the Robot
@StevenBurnap J'ai supprimé c ++ comme exemple, car vous avez raison.
Ampt
1
C'est aussi fait en php pour faciliter le chargement automatique. D'un autre côté, en php, vous pouvez déclarer explicitement un espace de noms.
Bodo

Réponses:

24

C'est bien. C'est bien aussi en C ++, pour référence.

Garder ensemble des choses étroitement couplées est une pratique judicieuse. Éviter un couplage inapproprié est également une bonne pratique. Trouver le bon équilibre n'est pas une question de règles strictes, mais bien de trouver un équilibre entre différentes préoccupations.

Quelques règles d'or:

  1. Taille

    Des fichiers excessivement volumineux peuvent être laids, mais ce n'est guère le cas ici. La laideur est probablement une raison suffisante pour diviser un fichier, mais développer ce sens esthétique est en grande partie une question d'expérience, donc cela ne vous aide pas à comprendre quoi faire a priori

  2. Séparation des préoccupations

    Si vos implémentations concrètes ont des préoccupations internes très différentes, votre fichier unique cumule toutes ces préoccupations. Par exemple, les implémentations avec des dépendances qui ne se chevauchent pas font que votre fichier unique dépend de l'union de toutes ces dépendances.

    Ainsi, il peut parfois être raisonnable de considérer que le couplage des sous-classes à leurs dépendances l'emporte sur leur couplage à l'interface (ou inversement, le souci d' implémenter une interface est plus faible que les préoccupations internes à cette implémentation).

    Comme exemple spécifique, prenez une interface de base de données générique. Les implémentations concrètes utilisant respectivement une base de données en mémoire, un SGBDR SQL et une requête Web peuvent n'avoir rien de commun en dehors de l'interface, et forcer tous ceux qui souhaitent que la version légère en mémoire importe également une bibliothèque SQL est désagréable.

  3. Encapsulation

    Bien que vous puissiez écrire des classes bien encapsulées dans le même module, cela pourrait encourager un couplage inutile simplement parce que vous avez accès à des détails d'implémentation qui autrement ne seraient pas exportés en dehors du module.

    C'est juste un mauvais style, je pense, mais vous pourriez imposer une meilleure discipline en divisant le module si vous ne pouvez vraiment pas rompre avec l'habitude.

Inutile
la source
2
Votre réponse serait plus forte si elle citait des références externes démontrant la normalité de combiner des classes dans un seul fichier, ou en fournissant plus d'explications indiquant pourquoi c'est OK.
1
J'ai édité la question pour souligner qu'il s'agit simplement d'un exemple de ce que je veux dire, et ne représente pas exactement la nature de la question. Pourquoi les conserver dans le même fichier est-il préférable de simplement les importer là où c'est nécessaire?
Ampt
Avoir beaucoup de petits fichiers peut être aussi difficile à gérer que d'avoir quelques fichiers géants. Python est un langage assez laconique. Votre exemple le montre. Ces trois classes sont directement liées et tiennent probablement dans une seule fenêtre d'éditeur sans défilement.
Gort the Robot
1
@ GlenH7 - Je ne suis pas sûr des références, car elles passent simplement de moi qui fait une réclamation directement à moi qui prétend que mon biais de sélection est valide. J'ai plutôt essayé de me concentrer sur l'explication.
inutile
7

Mes documents de référence habituels pour savoir ce qui est pythonique.

Simple, c'est mieux que complexe.

L'appartement est meilleur que l'emboîtement.

Du Zen Of Python

Presque sans exception, les noms de classe utilisent la convention CapWords.

Noms des modules et des modules Les modules doivent avoir des noms courts tout en minuscules. [...] Les noms des modules sont mappés aux noms de fichiers

De PEP 8

Mon interprétation est que c'est bien car cela garderait les choses simples et plates. De plus, comme les noms de classe et les noms de fichier ont des cas différents, ils ne sont pas censés être identiques de toute façon, donc je ne verrais aucun problème dans le regroupement de plusieurs classes liées dans un fichier.

SylvainD
la source
7
Pourriez-vous réduire cela aux parties pertinentes à la question? J'ai lu ces deux fois plusieurs fois mais j'ai du mal à choisir quelles parties en particulier se rapportent à ma question actuelle.
Ampt
1
En effet, j'ai édité ma réponse.
SylvainD
1

Ce que vous avez maintenant est très bien. Allez parcourir la bibliothèque standard - il y a beaucoup de modules avec plusieurs classes connexes dans un seul fichier. À un moment donné, les choses s'agrandissent et vous voudrez éventuellement commencer à utiliser des modules avec plusieurs fichiers, mais il n'y a pas de règles réelles quant au moment. Les choses sont simplement divisées lorsqu'un fichier commence à se sentir «trop gros».

Sean McSomething
la source
0

C'est très bien et je vous encourage à avoir plusieurs classes dans un seul fichier tant qu'elles sont réalisées. En général, vos classes doivent rester courtes et concises et vous devriez plutôt diviser le comportement en deux ou plusieurs classes plutôt que d'en créer d'énormes monolithiques. Lors de l'écriture de plusieurs petites classes, il est vraiment nécessaire et utile de conserver celles qui sont liées dans le même fichier.

wirrbel
la source
-1

En bref - enfer oui.

De plus, avoir plusieurs classes dans un seul fichier est parfois très pratique. Certains packages ( six, bottle) sont explicitement expédiés dans un seul fichier afin d'être facilement intégrés dans n'importe quel module tiers sans être installés par pip (parfois souhaitable). Mais assurez-vous de bien organiser votre code. Utilisez intensivement les commentaires de code et les blocs de séparation afin de le rendre plus lisible.

Artur Barseghyan
la source
3
cela ne semble pas ajouter quoi que ce soit de substantiel par rapport à la réponse précédente publiée il y a quelques années
gnat