2011-11-09 11 views
5

Estoy intentando estructurar mi aplicación en Python. Volviendo de C#/Java background, me gusta el enfoque de una clase por archivo. Me gustaría que mi árbol de proyecto para tener este aspecto:Python una clase por módulo y paquetes

[Service] 
    [Database] 
     DbClass1.py 
     DbClass2.py 
    [Model] 
     DbModel1.py 
     DbModel2.py 
    TheService.py 
[ServiceTests] 
    [Database] 
     DbClass1Tests.py 
     DbClass2Tests.py 
    [Model] 
     DbModel1Tests.py 
     DbModel2Tests.py 
    TheServiceTests.py 
  1. ¿Está el enfoque de una clase por archivo de OK en Python?
  2. ¿Es posible crear paquetes/módulos de tal manera para que los paquetes funcionan como paquetes de Java o espacios de nombres de .NET, es decir, en DbModel1Tests.py:

    import Service.Model 
    
    def test(): 
        m = DbModel1() 
    
+9

Es posible que quiera (en lugar de agruparlos en directorios como lo haría con la clase 1 por sistema de archivos.) eche un vistazo a [PEP 8 - Guía de estilo para el código de Python] (http://www.python.org/dev/peps/pep-0008/). –

Respuesta

4

En mi opinión, para 1: No veo por qué no. Creo que, independientemente del idioma, esta es una buena idea, ya que te proporciona una visión general rápida de lo que se puede encontrar en un archivo cuando sabes que habrá una sola clase en él. Aunque haría una pequeña excepción para las clases de ayuda, pero como Python permite las clases anidadas, esto también se puede hacer bastante bien.

Para 2: posible también. Sin embargo, en su ejemplo, simplemente carga el módulo, haciendo que sus clases y funciones estén disponibles en el espacio de nombre completo.

Por lo tanto, si dices import Service.Model, solo puedes acceder a la clase usando m = Service.Model.DBModel1().

Para importar cosas en el espacio de nombre actual, haga un from Service.Model import * (o from Service.Model import DBModel1 si solo necesita esa clase). Entonces puede hacer lo que hace actualmente: m = DBModel1().

+5

El final parece un poco engañoso: utilizando la estructura del OP, no sería necesario escribir 'm = DBModel1.DBModel1()' después de 'from Service.Model import DBModel1' (suponiendo que el nombre de clase es el mismo que el de .py archivo) ? – jwd

3

Puede tener una clase por módulo, pero esto no es obligatorio. Diría que está más relacionado con la duración de cada módulo (mantenerlos siempre es una buena idea).

Ahora, sobre su estructura:

  • puede declarar sus subcarpetas como paquetes. Para esto, solo crea un archivo __init__.py en cada subcarpeta.
  • una vez hecho esto, puede importar los módulos de la siguiente manera: from Service.Model import DbModel y utilizar esto como usted escribió: m = DbModel1.DbModel1Class()

Notas:

  • el nombramiento de su archivos con la primera letra en mayúscula no es realmente Pythonic (pero el nombre de clase debería tenerlo). Esto significa que debe verse como service.model.dbModel1.DbModel1().
  • puede hacer from Service.Model import DbModel1 para importar directamente la clase desde el módulo DbModel1. Esto se puede hacer mediante la configuración correcta del contenido __init__.py (no sé cómo configurarlo exactamente). Some more informations here.
13

Q1. Puede usar la clase 1 por estilo de archivo en Python, pero esto es inusual.

Q2. tendrías que usar from Service.Model import * y hacer algunas cosas en Service/Model/__init__.py que generalmente está mal visto.Evitar import * en Python

Mi consejo personal sobre esto: Python es no C#/Java. Intentar doblarlo para que se vea como $ other_language causará frustración y una mala experiencia del usuario.

Tenga en cuenta que:

  • que puede tener otras cosas que las clases en los módulos de Python (funciones, por ejemplo)
  • que no tienen que importar una clase a partir de un módulo a menos que necesite instanciar esa clase. Especialmente, si su código solo usa instancias de DbModel1 que se pasan como argumentos a sus funciones/métodos, no hay necesidad de importar en esa parte del código
  • de Service.Model.DbModel1 import DbModel1 que parece estar mal. Prefiere from service.model import DbModel1: evitar que las letras mayúsculas en nombres de archivos y directorios, y las clases de grupo/funciones lógicamente en archivos
+0

¿Por qué una clase de archivo es inusual en Python? – Gewthen

+0

@Gewthen no es obligatorio por el idioma, por lo que no es una práctica común. –

+1

Independientemente de si estoy de acuerdo o en desacuerdo, esta respuesta podría ser más útil si algunos de los "hacer y no hacer" tienen alguna explicación y razonamiento detrás de ellos. Mencionar pep 8 podría ayudar en algunos de sus puntos, pero otros necesitan más (por ejemplo, "generalmente mal visto", "se ve mal"). – Gewthen

Cuestiones relacionadas