Pregunta ¿Cuál es la mejor estructura de proyecto para una aplicación Python? [cerrado]


Imagine que desea desarrollar una aplicación de escritorio de usuario final no trivial (no web) en Python. ¿Cuál es la mejor forma de estructurar la jerarquía de carpetas del proyecto?

Las características deseables son facilidad de mantenimiento, compatibilidad con IDE, idoneidad para la bifurcación / fusión de control de fuente y generación sencilla de paquetes de instalación.

En particular:

  1. ¿Dónde colocas la fuente?
  2. ¿Dónde colocas las secuencias de comandos de inicio de la aplicación?
  3. ¿Dónde colocas el proyecto IDE Cruft?
  4. ¿Dónde colocas las pruebas de unidad / aceptación?
  5. ¿Dónde colocas datos que no son de Python, como los archivos de configuración?
  6. ¿Dónde colocas fuentes que no son de Python, como C ++, para módulos de extensión binarios / pyd / so?

572
2017-10-10 21:50


origen


Respuestas:


No importa demasiado. Lo que te haga feliz funcionará. No hay muchas reglas tontas porque los proyectos de Python pueden ser simples.

  • /scripts o /bin para ese tipo de cosas de interfaz de línea de comandos
  • /tests para tus pruebas
  • /lib para sus bibliotecas de C-language
  • /doc para la mayoría de la documentación
  • /apidoc para los documentos API generados por Epydoc.

Y el directorio de nivel superior puede contener README, Config y whatnot.

La elección difícil es si usar o no un /src árbol. Python no tiene una distinción entre /src, /liby /bin como Java o C tiene.

Desde un nivel superior /src directorio es visto por algunos como sin sentido, su directorio de nivel superior puede ser la arquitectura de nivel superior de su aplicación.

  • /foo
  • /bar
  • /baz

Recomiendo poner todo esto bajo el directorio "nombre de mi producto". Entonces, si estás escribiendo una aplicación llamada quux, el directorio que contiene todo esto se llama /quux.

Otro proyecto PYTHONPATH, entonces, puede incluir /path/to/quux/foo reutilizar el QUUX.foo módulo.

En mi caso, dado que uso Komodo Edit, mi IDE cuft es un archivo .KPF único. De hecho lo puse en el nivel superior /quux directorio, y omita agregarlo a SVN.


303
2017-10-10 22:03



De acuerdo con Jean-Paul Calderone's Estructura del sistema de archivos de un proyecto de Python:

Project/
|-- bin/
|   |-- project
|
|-- project/
|   |-- test/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |   
|   |-- __init__.py
|   |-- main.py
|
|-- setup.py
|-- README

197
2018-05-13 23:49



Esta publicación de blog de Jean-Paul Calderone se suele dar como respuesta en #python en Freenode.

Estructura del sistema de archivos de un proyecto de Python

Hacer:

  • nombre el directorio algo relacionado con su proyecto. Por ejemplo, si su proyecto se llama "Trenzado", nombre el directorio de nivel superior para sus archivos fuente Twisted. Cuando haga lanzamientos, debe incluir un sufijo de número de versión: Twisted-2.5.
  • crea un directorio Twisted/bin y pon tus ejecutables allí, si tienes alguno. No les des un .py extensión, incluso si son archivos fuente de Python. No coloque ningún código en ellos excepto una importación de y llame a una función principal definida en otro lugar en sus proyectos. (Ligera arruga: ya que en Windows, el intérprete está seleccionado por la extensión de archivo, los usuarios de Windows realmente quieren la extensión .py. Por lo tanto, cuando empaque para Windows, es posible que desee agregarlo. Desafortunadamente no hay truco fácil de distutils que Sé de automatizar este proceso. Considerando que en POSIX la extensión .py es solo una verruga, mientras que en Windows la falta es un error real, si su base de usuarios incluye usuarios de Windows, puede optar por simplemente tener el .py extensión en todas partes)
  • Si su proyecto se puede expresar como un único archivo fuente de Python, póngalo en el directorio y nómbrelo algo relacionado con su proyecto. Por ejemplo, Twisted/twisted.py. Si necesita varios archivos de origen, cree un paquete en su lugar (Twisted/twisted/, con un vacío Twisted/twisted/__init__.py) y coloque sus archivos fuente en él. Por ejemplo, Twisted/twisted/internet.py.
  • ponga las pruebas de su unidad en un subpaquete de su paquete (nota: esto significa que la única opción del archivo fuente de Python anterior fue un truco) siempre necesita al menos otro archivo para las pruebas de su unidad). Por ejemplo, Twisted/twisted/test/. Por supuesto, hazlo un paquete con Twisted/twisted/test/__init__.py. Coloque las pruebas en archivos como Twisted/twisted/test/test_internet.py.
  • añadir Twisted/README y Twisted/setup.py para explicar e instalar su software, respectivamente, si se siente bien.

No hacer:

  • pon tu fuente en un directorio llamado src o lib. Esto hace que sea difícil ejecutar sin instalar.
  • pon tus pruebas fuera de tu paquete de Python. Esto hace que sea difícil ejecutar las pruebas en una versión instalada.
  • crea un paquete que solamente tiene un __init__.py y luego poner todo tu código en __init__.py. Solo crea un módulo en lugar de un paquete, es más simple.
  • Intente crear hacks mágicos para que Python pueda importar su módulo o paquete sin que el usuario agregue el directorio que lo contiene a su ruta de importación (ya sea a través de PYTHONPATH u otro mecanismo). Vas a no maneje correctamente todos los casos y los usuarios se enojarán con usted cuando su software no funcione en su entorno.

180
2017-08-05 23:29



Revisa Abrir Sourcing a un proyecto de Python de la manera correcta.

Permítanme extraer el diseño del proyecto parte de ese excelente artículo:

Al configurar un proyecto, el diseño (o la estructura del directorio) es importante para hacerlo bien. Un diseño sensato significa que los posibles contribuyentes no tienen que gastar siempre buscando un código; la ubicación de los archivos es intuitiva. Como estamos tratando con un proyecto existente, significa que probablemente deba mover algunas cosas.

Comencemos en la parte superior. La mayoría de los proyectos tienen varios archivos de nivel superior (como setup.py, README.md, requirements.txt, etc.). Entonces hay tres directorios que cada proyecto debe tener:

  • Un directorio de documentos que contiene la documentación del proyecto
  • Un directorio nombrado con el nombre del proyecto que almacena el paquete real de Python
  • Un directorio de prueba en uno de dos lugares   
    • En el directorio del paquete que contiene el código de prueba y los recursos
    • Como un directorio de nivel superior independiente   Para tener una mejor idea de cómo deberían organizarse sus archivos, aquí hay una instantánea simplificada del diseño de uno de mis proyectos, sandman:
$ pwd
~/code/sandman
$ tree
.
|- LICENSE
|- README.md
|- TODO.md
|- docs
|   |-- conf.py
|   |-- generated
|   |-- index.rst
|   |-- installation.rst
|   |-- modules.rst
|   |-- quickstart.rst
|   |-- sandman.rst
|- requirements.txt
|- sandman
|   |-- __init__.py
|   |-- exception.py
|   |-- model.py
|   |-- sandman.py
|   |-- test
|       |-- models.py
|       |-- test_sandman.py
|- setup.py

Como puede ver, hay algunos archivos de nivel superior, un directorio de documentos (generado es un directorio vacío donde sphinx colocará la documentación generada), un directorio de sandman y un directorio de prueba bajo sandman.


94
2017-11-09 02:22



La "Autoridad de empaque de Python" tiene un proyecto de ejemplo:

https://github.com/pypa/sampleproject

Es un proyecto de muestra que existe como una ayuda para el Tutorial de la Guía de usuario de empaquetado de Python en proyectos de empaquetado y distribución.


16
2018-06-12 09:23



Intente comenzar el proyecto usando el python_boilerplate modelo. En gran parte sigue las mejores prácticas (p. esos aquí), pero es más adecuado en caso de que te encuentres dispuesto a dividir tu proyecto en más de un huevo en algún momento (y créeme, con todo menos los proyectos más simples, lo harás. Una situación común es cuando tienes que usar un local versión modificada de la biblioteca de otra persona).

  • ¿Dónde colocas la fuente?

    • Para proyectos decentemente grandes, tiene sentido dividir la fuente en varios huevos. Cada huevo iría como una disposición de herramientas de configuración separada bajo PROJECT_ROOT/src/<egg_name>.
  • ¿Dónde colocas las secuencias de comandos de inicio de la aplicación?

    • La opción ideal es tener el script de inicio de la aplicación registrado como entry_point en uno de los huevos.
  • ¿Dónde colocas el proyecto IDE Cruft?

    • Depende del IDE. Muchos de ellos mantienen sus cosas en PROJECT_ROOT/.<something> en la raíz del proyecto, y esto está bien.
  • ¿Dónde colocas las pruebas de unidad / aceptación?

    • Cada huevo tiene un conjunto separado de pruebas, guardadas en PROJECT_ROOT/src/<egg_name>/tests directorio. Yo personalmente prefiero usar py.test para ejecutarlos.
  • ¿Dónde colocas datos que no son de Python, como los archivos de configuración?

    • Depende. Puede haber diferentes tipos de datos que no sean de Python.
      • "Recursos", es decir, datos que deben estar empaquetados dentro de un huevo. Estos datos van al directorio de hueveras correspondiente, en algún lugar dentro del espacio de nombres del paquete. Se puede usar a través de pkg_resources paquete.
      • "Config-files", es decir, archivos que no son de Python que deben considerarse externos a los archivos fuente del proyecto, pero que deben inicializarse con algunos valores cuando la aplicación se inicia. Durante el desarrollo, prefiero mantener esos archivos en PROJECT_ROOT/config. Para el despliegue puede haber varias opciones. En Windows uno puede usar %APP_DATA%/<app-name>/config, en Linux, /etc/<app-name> o /opt/<app-name>/config.
      • Archivos generados, es decir, archivos que la aplicación puede crear o modificar durante la ejecución. Preferiría mantenerlos en PROJECT_ROOT/var durante el desarrollo, y bajo /var durante la implementación de Linux.
  • ¿Dónde colocas fuentes que no son de Python, como C ++, para módulos de extensión binarios / pyd / so?
    • Dentro PROJECT_ROOT/src/<egg_name>/native

La documentación típicamente entraría en PROJECT_ROOT/doc o PROJECT_ROOT/src/<egg_name>/doc (Esto depende de si considera que algunos de los huevos son proyectos separados). Alguna configuración adicional estará en archivos como PROJECT_ROOT/buildout.cfg y PROJECT_ROOT/setup.cfg.


15
2018-03-21 09:17



En mi experiencia, es solo una cuestión de iteración. Pon tus datos y código donde creas que van. Lo más probable es que te equivoques de todos modos. Pero una vez que tienes una mejor idea de cómo van a evolucionar las cosas, estás en una posición mucho mejor para hacer este tipo de conjeturas.

En cuanto a las fuentes de extensión, tenemos un directorio de código en trunk que contiene un directorio para python y un directorio para varios otros idiomas. Personalmente, estoy más inclinado a tratar de poner cualquier código de extensión en su propio repositorio la próxima vez.

Dicho esto, vuelvo a mi punto inicial: no hagas un gran pacto con eso. Ponlo en un lugar que parezca funcionar para ti. Si encuentra algo que no funciona, puede (y debe) cambiarse.


13
2017-10-10 22:57



Los datos que no son de Python se integran mejor dentro de los módulos de Python usando el package_data apoyo en la setuptools. Una cosa que recomiendo encarecidamente es usar paquetes de espacio de nombres para crear espacios de nombres compartidos que múltiples proyectos puedan usar, al igual que la convención de Java de poner paquetes en com.yourcompany.yourproject(y poder compartir com.yourcompany.utils espacio de nombres).

Re bifurcación y fusión, si usa un sistema de control de fuente lo suficientemente bueno manejará fusiones incluso a través de renombrados; Bazar es particularmente bueno en esto.

Contrariamente a algunas otras respuestas aquí, tengo +1 al tener una src directorio de nivel superior (con doc y test directorios al costado). Las convenciones específicas para árboles de directorios de documentación variarán dependiendo de lo que esté usando; Esfinge, por ejemplo, tiene sus propias convenciones que admite su herramienta de inicio rápido.

Por favor, aproveche setuptools y pkg_resources; esto hace que sea mucho más fácil para otros proyectos confiar en versiones específicas de su código (y para que múltiples versiones se instalen simultáneamente con diferentes archivos que no sean de código, si está utilizando package_data)


7
2017-10-10 22:39