python - barplot - pandas plot
La manera Pythonic de organizar módulos y paquetes (5)
Como una guía vaga: más de 1 clase por archivo es la norma para python
también, mira ¿Cuántas clases de Python debería poner en un archivo?
Vengo de un entorno en el que normalmente creo un archivo por clase. Organizo clases comunes bajo directorios también. Esta práctica es intuitiva para mí y se ha demostrado que es efectiva en C ++, PHP, JavaSript, etc.
Tengo problemas para llevar esta metáfora a Python: los archivos ya no son solo archivos, sino que son módulos formales. No parece correcto tener solo una clase en un módulo, la mayoría de las clases son inútiles por sí mismas. Si tengo un automobile.py
y una clase de Automobile
, me parece tonto siempre referirme a él como automobile.Automobile
. automobile.Automobile
también.
Pero, al mismo tiempo, no parece correcto arrojar una tonelada de código en un archivo y llamarlo un día. Obviamente, una aplicación muy compleja debería tener más de 5 archivos.
¿Cuál es la forma correcta --- o pythonic ---? (O si no hay una forma correcta, ¿cuál es su forma preferida y por qué?) ¿Cuánto código debería lanzar en un módulo de Python?
En un proyecto de tamaño medio, me encontré con varios conjuntos de clases estrechamente relacionadas. Varios de esos conjuntos ahora están agrupados en archivos; por ejemplo, las clases de red de bajo nivel están todas en un solo módulo de network
. Sin embargo, algunas de las clases más grandes se han dividido en su propio archivo.
Tal vez la mejor manera de comenzar ese camino desde un historial de una clase por archivo es tomar las clases que normalmente colocaría en el mismo directorio y, en su lugar, mantenerlas en el mismo archivo. Si ese archivo comienza a parecer demasiado grande, divídelo.
Piense en términos de una "unidad lógica de empaquetamiento", que puede ser una única clase, pero más a menudo será un conjunto de clases que cooperen estrechamente. Las clases (o funciones de nivel de módulo: "no hacer Java en Python" utilizando siempre métodos estáticos cuando las funciones de nivel de módulo también están disponibles como opción) -) se pueden agrupar según este criterio. Básicamente, si la mayoría de los usuarios de A también necesitan B y viceversa, A y B probablemente deberían estar en el mismo módulo; pero si muchos usuarios solo necesitarán uno y no el otro, entonces probablemente deberían estar en módulos distintos (tal vez en el mismo paquete, es decir, directorio con un archivo __init__.py
).
La biblioteca estándar de Python, aunque está lejos de ser perfecta, tiende a reflejar (en su mayoría) prácticas razonablemente buenas, por lo que puede aprender de ella principalmente con el ejemplo. Por ejemplo, el módulo de threading
, por supuesto, define una clase de Thread
... pero también contiene las clases de primitiva de sincronización, como bloqueos, eventos, condiciones y semáforos, y una clase de excepción que se puede generar mediante operaciones de subprocesamiento (y algunas más cosas). Está en el límite superior de tamaño razonable (800 líneas incluyendo espacios en blanco y cadenas de documentos), y algunas funcionalidades cruciales relacionadas con hilos tales como Queue se han colocado en un módulo separado, sin embargo es un buen ejemplo de qué cantidad máxima de funcionalidad todavía tiene sentido empacar en un solo módulo.
Si desea mantener su sistema de una sola clase por archivo (que es lógico, no me malinterprete), puede hacer algo como esto para evitar tener que referirse al automobile.Automobile
. automobile.Automobile
:
from automobile import Automobile
car = Automobile()
Sin embargo, como mencionó cobbal, más de una clase por archivo es bastante común en Python. De cualquier manera, siempre y cuando elijas un sistema sensato y lo uses de manera consistente, no creo que ningún usuario de Python se enoje contigo :).
Si vienes desde un punto de vista de c ++, podrías ver módulos de Python similares a .so o .dll. Sí, parecen archivos de origen, porque Python tiene secuencias de comandos, pero en realidad son bibliotecas cargables de funcionalidades específicas.
Otra metáfora que puede ayudar es que podría ver los módulos de Python como espacios de nombres.