web-dev-qa-db-fra.com

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

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.

The Question: Est-ce standard pour python, ou pour n'importe quel langage? Quels problèmes pourraient résulter de l'utilisation de cette implémentation, le cas échéant?

EDIT: Je ne suis pas vraiment à la recherche de conseils sur ce fichier 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 diviser alors? Où est la limite pour dire que vous devez diviser un fichier?

32
Ampt

C'est bon. 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 de 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 en 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 méchant.

  3. Encapsulation

    Bien que vous pouvez é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 ne seraient pas autrement 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.

27
Useless

Mes documents de référence habituels pour savoir ce qu'est Pythonic.

Simple, c'est mieux que complexe.

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

De Le zen de 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.

7
SylvainD

Ce que vous avez maintenant est très bien. Allez parcourir la bibliothèque standard - il y a beaucoup de modules avec plusieurs classes liées 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 vraies règles quant au moment. Les choses sont simplement divisées lorsqu'un fichier commence à se sentir "trop gros".

1
Sean McSomething

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.

0
wirrbel