¿Se considera Pythonic tener múltiples clases definidas en el mismo archivo?

31

Al trabajar con Python por primera vez, descubrí que termino escribiendo varias clases en el mismo archivo, lo que se opone a otros lenguajes como Java, que usa un archivo por clase.

Por lo general, estas clases están formadas por 1 clase base abstracta, con 1-2 implementaciones concretas cuyo uso varía ligeramente. He publicado uno de estos archivos a continuación:

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

Como se ve arriba, tengo una clase base Logger, con un par de diferencias de implementación por debajo de eso.

La pregunta: ¿Es este estándar para Python o para cualquier idioma? ¿Qué problemas podrían surgir al usar esta implementación si existe?

EDITAR: Realmente no estoy buscando orientación sobre este archivo específico , pero en un sentido más general. ¿Qué pasa si las clases terminaron siendo 3-5 métodos moderadamente complejos? ¿Tendría sentido dividirlos entonces? ¿Dónde está el límite para decir que debe dividir un archivo?

Ampt
fuente
3
Limitar a una clase por archivo NO es una cosa de C ++. Java es el único lenguaje que conozco donde se considera algo que debe evitarse. En C ++, es extremadamente común que un solo archivo .h / .cpp tenga una clase primaria y muchas clases auxiliares, que pueden o no ser privadas para la clase primaria.
Gort the Robot
@StevenBurnap Eliminé c ++ como ejemplo, ya que tienes razón.
Ampt
1
También se hace en PHP para facilitar la carga automática. Por otro lado, en php puede declarar explícitamente el espacio de nombres.
Bodo

Respuestas:

24

Está bien. También está bien en C ++, como referencia.

Mantener unidas las cosas juntas es una práctica sensata. Evitar el acoplamiento inapropiado también es una buena práctica. Lograr el equilibrio correcto no es una cuestión de reglas estrictas, sino de, bueno, lograr un equilibrio entre diferentes preocupaciones.

Algunas reglas generales:

  1. tamaño

    Los archivos excesivamente grandes pueden ser feos, pero ese no es el caso aquí. La fealdad es probablemente una razón suficiente para dividir un archivo, pero desarrollar ese sentido estético es en gran medida una cuestión de experiencia, por lo que no te ayuda a descubrir qué hacer a priori

  2. Separación de intereses

    Si sus implementaciones concretas tienen preocupaciones internas muy diferentes, su archivo único acumula todas esas preocupaciones. Por ejemplo, las implementaciones con dependencias no superpuestas hacen que su archivo único dependa de la unión de todas esas dependencias.

    Por lo tanto, a veces puede ser razonable considerar que el acoplamiento de las subclases a sus dependencias supera su acoplamiento a la interfaz (o, por el contrario, la preocupación de implementar una interfaz es más débil que las preocupaciones internas de esa implementación).

    Como ejemplo específico, tome una interfaz de base de datos genérica. Las implementaciones concretas que usan un DB en memoria, un RDBMS de SQL y una consulta web respectivamente pueden no tener nada en común aparte de la interfaz, y obligar a todos los que quieran que la versión ligera en memoria también importe una biblioteca SQL es desagradable.

  3. Encapsulamiento

    Aunque puede escribir clases bien encapsuladas en el mismo módulo, podría fomentar un acoplamiento innecesario solo porque tiene acceso a detalles de implementación que de otro modo no se exportarían fuera del módulo.

    Creo que este es un estilo pobre, pero podría imponer una mejor disciplina dividiendo el módulo si realmente no puede romper el hábito.

Inútil
fuente
2
Su respuesta sería más fuerte si citara referencias externas que demostraran la normalidad de combinar clases en un archivo, o al proporcionar más explicaciones que indiquen por qué está bien.
1
He editado la pregunta para señalar que esto es simplemente un ejemplo de lo que quiero decir, y no representa exactamente la naturaleza de la pregunta. ¿Por qué es mejor mantenerlos en el mismo archivo que simplemente importarlos donde sea necesario?
Ampt
Tener muchos archivos pequeños puede ser tan difícil de administrar como tener algunos archivos gigantes. Python es un lenguaje bastante conciso. Tu ejemplo muestra esto. Esas tres clases están directamente relacionadas y probablemente encajan en una sola ventana del editor sin desplazarse.
Gort the Robot
1
@ GlenH7: no estoy seguro acerca de las referencias, ya que simplemente cambian de mí haciendo un reclamo directamente, a mí alegando que mi sesgo de selección es válido. He tratado de centrarme en la explicación en su lugar.
Inútil
7

Mis documentos de referencia habituales para saber qué es pitónico.

Simple es mejor que complejo.

Plano es mejor que anidado.

Del zen de Python

Casi sin excepción, los nombres de clase usan la convención CapWords.

Nombres de paquetes y módulos Los módulos deben tener nombres cortos en minúsculas. [...] Los nombres de los módulos se asignan a los nombres de archivo

De PEP 8

Mi interpretación es que está bien, ya que mantendría las cosas simples y planas. Además, debido a que los nombres de clase y los nombres de archivo tienen diferentes casos, no se supone que sean idénticos de todos modos, por lo que no vería ningún problema en empacar varias clases relacionadas en un archivo.

SylvainD
fuente
77
¿Podría reducir esto a las partes relevantes de la pregunta? He leído ambas veces varias veces, pero me cuesta elegir qué partes en particular se relacionan con mi pregunta actual.
Ampt
1
De hecho, he editado mi respuesta.
SylvainD
1

Lo que tienes ahora está bien. Vaya y explore la biblioteca estándar: hay muchos módulos con múltiples clases relacionadas en un solo archivo. En algún momento, las cosas se hacen más grandes y eventualmente querrás comenzar a usar módulos con múltiples archivos, pero no hay reglas reales sobre cuándo. Las cosas simplemente se dividen cuando un archivo comienza a sentirse "demasiado grande".

Sean McSomething
fuente
0

Definitivamente está bien y te animo a que tengas varias clases en un archivo siempre que estén relacionadas. En general, sus clases deben ser breves y concisas, y debe dividir el comportamiento en dos o más clases que construir grandes monolíticos. Al escribir varias clases pequeñas, es realmente necesario y útil mantener las que están relacionadas en el mismo archivo.

wirrbel
fuente
-1

En resumen, demonios sí.

Además, tener varias clases en un solo archivo a veces es muy útil. Algunos paquetes ( six, bottle) se envían explícitamente en un solo archivo para integrarse fácilmente en cualquier módulo de terceros sin ser instalado por pip (a veces deseable). Pero asegúrese de organizar bien su código. Utilice intensivamente los comentarios de código y los bloques de separación para que sea más legible.

Artur Barseghyan
fuente
3
Esto no parece agregar nada sustancial sobre la respuesta anterior publicada hace unos años
mosquito