Implementación de una aplicación python con paquete compartido
-
11-07-2019 - |
Pregunta
Estoy pensando en cómo organizar una aplicación Python implementada que tendrá un
- Script ejecutable ubicado en / usr / bin / que proporcionará una CLI a la funcionalidad implementada en
- Una biblioteca instalada donde sea que esté el directorio actual de paquetes de sitio.
Ahora, actualmente, tengo la siguiente estructura de directorios en mis fuentes:
foo.py
foo/
__init__.py
...
que supongo que no es la mejor manera de hacer las cosas. Durante el desarrollo, todo funciona como se esperaba, sin embargo, cuando se implementa, el "foo import FooObject" el código en foo.py aparentemente intenta importar foo.py, que no es el comportamiento que estoy buscando.
Entonces, la pregunta es ¿cuál es la práctica estándar de orquestar situaciones como esta? Una de las cosas en las que puedo pensar es, al instalar, cambiar el nombre de foo.py a solo foo, lo que impide que se importe, pero eso parece bastante incómodo ...
Supongo que otra parte del problema es que es un desafío de nombres. ¿Quizás llamar al script ejecutable foo-bin.py?
Solución
Este artículo es bastante bueno y le muestra una buena manera de hacerlo. El segundo elemento de la lista Hacer responde a su pregunta.
pegar copia desvergonzada:
Estructura del sistema de archivos de un proyecto de Python
por Jp Calderone
Do:
- nombra el directorio algo relacionado con tu proyecto. Por ejemplo, si tu el proyecto se llama " Twisted " ;, nombra el directorio de nivel superior para su fuente archivos
Twisted
. Cuando haces lanzamientos, debes incluir un número de versión sufijo:Twisted-2.5
.- crea un directorio
Twisted / bin
y coloca tus ejecutables allí, si tener alguno. No les des un.py
extensión, incluso si son Python archivos fuente. No pongas ningún código en ellos excepto una importación de y llamar a un función principal definida en otro lugar en tus proyectos.- Si su proyecto se puede expresar como un único archivo fuente de Python, póngalo en el directorio y nómbralo algo relacionado con tu proyecto. por ejemplo,
Twisted / twisted.py
. Si tu necesita múltiples archivos fuente, crea un paquete en su lugar (Twisted / twisted /
, con un vacioTwisted / twisted / __ init__.py
) y colocar sus archivos fuente en el mismo. Por ejemplo,Twisted / twisted / internet.py
.- ponga sus pruebas unitarias en un subpaquete de su paquete (nota: esto significa que el único archivo fuente de Python la opción anterior fue un truco: siempre necesita al menos otro archivo para su pruebas unitarias). Por ejemplo,
Twisted / twisted / test /
. Por supuesto, hacer es un paquete conTwisted / twisted / test / __ init__.py
. Colocar pruebas en archivos comoTwisted / twisted / test / test_internet.py
.- agregue
Twisted / README
yTwisted / setup.py
para explicar y instale su software, respectivamente, si te sientes bien.No :
- ponga su fuente en un directorio llamado
src
olib
. Esto lo hace dificil ejecutar sin instalar.- ponga sus pruebas fuera de su paquete Python. Esto hace que sea difícil ejecutar las pruebas contra un instalado versión.
- cree un paquete que solo tenga un
__init__.py
y luego coloque todo su código en__init__.py
. Solo haz un módulo en lugar de un paquete, es más simple.- intenta crear trucos mágicos para que Python pueda importar tu 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
o algún otro mecanismo). No lo harás manejar correctamente todos los casos y usuarios se enojará contigo cuando tu el software no funciona en su medio ambiente.
Otros consejos
Distutils admite la instalación de módulos, paquetes y scripts . Si crea un distcodes setup.py
que se refiere a foo
como paquete y foo.py
como script, entonces foo. py
debe instalarse en / usr / local / bin
o cualquiera que sea la ruta de instalación de script adecuada en el sistema operativo de destino, y el paquete foo
debe instalarse en el directorio site_packages
.
Debe llamar al ejecutable solo foo
, no foo.py
, luego los intentos de importar foo no lo usarán.
En cuanto a nombrarlo correctamente: esto es difícil de responder en abstracto; necesitaríamos saber qué hace específicamente. Por ejemplo, si configura y controla, llamarlo -config o ctl podría ser apropiado. Si es una API de shell para la biblioteca, debería tener el mismo nombre que la biblioteca.
Su módulo CLI es una cosa, el paquete que lo admite es otra. No confunda los nombres con el módulo foo
(en un archivo foo.py
) y el paquete foo
(en un directorio foo
con un archivo __init__.py
).
Tienes dos cosas llamadas foo
: un módulo y un paquete. ¿Qué más quieres nombrar foo
? ¿Una clase? ¿Una función? ¿Una variable?
Elija un nombre distintivo para el módulo foo o el paquete foo. foolib
, por ejemplo, es un nombre de paquete popular.