Imagine que desea desarrollar una aplicación de escritorio de usuario final (no web) no trivial en Python. ¿Cuál es la mejor manera de estructurar la jerarquía de carpetas del proyecto?
Las características deseables son la facilidad de mantenimiento, la compatibilidad con IDE, la idoneidad para la ramificación / fusión del control de origen y la fácil generación de paquetes de instalación.
En particular:
- ¿Dónde pones la fuente?
- ¿Dónde pones los scripts de inicio de la aplicación?
- ¿Dónde pones el proyecto IDE cruft?
- ¿Dónde pones las pruebas de unidad / aceptación?
- ¿Dónde coloca los datos que no son de Python, como los archivos de configuración?
- ¿Dónde coloca las fuentes que no son de Python como C ++ para módulos de extensión binaria pyd / so?
De acuerdo con la estructura del sistema de archivos de Jean-Paul Calderone de un proyecto de Python :
fuente
Project/project/
? Ah, el segundo es el nombre del paquete.../
en una declaración de inclusión)pip install -e /path/to/Project
)-e
bandera, que instala el paquete como un paquete editable, es decir, lo instala como enlaces a la carpeta del proyecto real. El ejecutable puede entonces simplementeimport project
tener acceso al módulo.Esta publicación de blog de Jean-Paul Calderone se da comúnmente como respuesta en #python en Freenode.
fuente
Echa un vistazo a Open Sourcing a Python Project de la manera correcta .
Permítanme extraer la parte del diseño del proyecto de ese excelente artículo:
fuente
Makefile
al mismo nivel quesetup.py
? Entonces, si entiendo quemake env
automatiza correctamente la creación de un nuevovenv
e instala los paquetes en él ...La "Autoridad de Empaque de Python" tiene un proyecto de muestra:
https://github.com/pypa/sampleproject
Es un proyecto de muestra que existe como ayuda para el Tutorial de la Guía del usuario de Python Packaging sobre Empaquetado y Distribución de Proyectos.
fuente
root/src/*
estructura: github.com/pypa/sampleproject/commit/…Intente iniciar el proyecto utilizando la plantilla python_boilerplate . Sigue en gran medida las mejores prácticas (por ejemplo, las de aquí ), pero es más adecuado en caso de que esté dispuesto a dividir su proyecto en más de un huevo en algún momento (y créame, con cualquier cosa menos los proyectos más simples, lo hará. Uno) Una situación común es cuando tiene que usar una versión modificada localmente de la biblioteca de otra persona).
¿Dónde pones la fuente?
PROJECT_ROOT/src/<egg_name>
.¿Dónde pones los scripts de inicio de la aplicación?
entry_point
uno de los huevos.¿Dónde pones el proyecto IDE cruft?
PROJECT_ROOT/.<something>
la raíz del proyecto, y esto está bien.¿Dónde pones las pruebas de unidad / aceptación?
PROJECT_ROOT/src/<egg_name>/tests
directorio. Personalmente prefiero usarpy.test
para ejecutarlos.¿Dónde coloca los datos que no son de Python, como los archivos de configuración?
pkg_resources
paquete desdesetuptools
, o desde Python 3.7 a través delimportlib.resources
módulo de la biblioteca estándar.PROJECT_ROOT/config
. Para la implementación puede haber varias opciones. En Windows se puede usar%APP_DATA%/<app-name>/config
, en Linux/etc/<app-name>
o/opt/<app-name>/config
.PROJECT_ROOT/var
durante el desarrollo y debajo/var
durante la implementación de Linux.PROJECT_ROOT/src/<egg_name>/native
La documentación generalmente entraría
PROJECT_ROOT/doc
oPROJECT_ROOT/src/<egg_name>/doc
(esto depende de si considera que algunos de los huevos son proyectos grandes separados). Alguna configuración adicional estará en archivos comoPROJECT_ROOT/buildout.cfg
yPROJECT_ROOT/setup.cfg
.fuente
base_data_location
variable, pero ¿cómo la configuras adecuadamente?En mi experiencia, es solo una cuestión de iteración. Ponga sus datos y código donde quiera que vaya. Lo más probable es que te equivoques de todos modos. Pero una vez que tenga una mejor idea de cómo se van a arreglar las cosas, estará 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 debajo del tronco que contiene un directorio para python y un directorio para varios otros idiomas. Personalmente, estoy más inclinado a intentar 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 problema. Ponlo en un lugar que parezca funcionar para ti. Si encuentra algo que no funciona, puede (y debería) cambiarse.
fuente
Los datos que no son de Python se agrupan mejor dentro de sus módulos de Python utilizando el
package_data
soporte en setuptools . Una cosa que recomiendo encarecidamente es usar paquetes de espacio de nombres para crear espacios de nombres compartidos que pueden usar múltiples proyectos, al igual que la convención de Java de colocar paquetescom.yourcompany.yourproject
(y poder tener un espacio compartidocom.yourcompany.utils
espacio de nombres ).Re ramificación y fusión, si usa un sistema de control de fuente lo suficientemente bueno, manejará las fusiones incluso a través de cambios de nombre; Bazar es particularmente bueno en esto.
Al contrario de algunas otras respuestas aquí, estoy +1 en tener un
src
directorio de nivel superior (condoc
ytest
directorios al lado). Las convenciones específicas para los árboles de directorios de documentación variarán según lo que esté utilizando; Sphinx , 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 varias versiones se instalen simultáneamente con diferentes archivos sin código, si está usando
package_data
).fuente