interesantes - Administrar recursos en un proyecto de Python
proyectos en python 3 (3)
Siempre puede tener una carpeta de "recursos" por separado en cada subpaquete que lo necesite, y usar las funciones de os.path
para llegar a ellos desde los valores de __file__ de sus subpaquetes. Para ilustrar lo que quiero decir, creé el siguiente archivo __init__.py
en tres ubicaciones:
c:/temp/topp (top-level package) c:/temp/topp/sub1 (subpackage 1) c:/temp/topp/sub2 (subpackage 2)
Aquí está el archivo __init__.py
:
import os.path
resource_path = os.path.join(os.path.split(__file__)[0], "resources")
print resource_path
En c: / temp / work, creo una aplicación, topapp.py, de la siguiente manera:
import topp
import topp.sub1
import topp.sub2
Esto representa la aplicación utilizando el paquete topp
y los subpaquetes. Entonces lo ejecuto:
C:/temp/work>topapp Traceback (most recent call last): File "C:/temp/work/topapp.py", line 1, in import topp ImportError: No module named topp
Eso es lo esperado. Configuramos el PYTHONPATH para simular tener nuestro paquete en la ruta:
C:/temp/work>set PYTHONPATH=c:/temp C:/temp/work>topapp c:/temp/topp/resources c:/temp/topp/sub1/resources c:/temp/topp/sub2/resources
Como puede ver, las rutas de recursos se resolvieron correctamente a la ubicación de los paquetes (sub) reales en la ruta.
Actualización: aquí está la documentación relevante de py2exe.
Tengo un proyecto de Python en el que estoy usando muchos archivos que no son de código. Actualmente estas son todas las imágenes, pero podría usar otros tipos de archivos en el futuro. ¿Cuál sería un buen esquema para almacenar y hacer referencia a estos archivos?
Consideré simplemente hacer una carpeta de "recursos" en el directorio principal, pero hay un problema; Algunas imágenes se usan desde subpaquetes de mi proyecto. Almacenar estas imágenes de esa manera conduciría al acoplamiento, lo cual es una desventaja.
Además, necesito una forma de acceder a estos archivos, que es independiente de lo que es mi directorio actual.
Es posible que desee utilizar la biblioteca pkg_resources
que viene con las setuptools
.
Por ejemplo, inventé un pequeño y rápido paquete "proj"
para ilustrar el esquema de organización de recursos que usaría:
proj/setup.py proj/proj/__init__.py proj/proj/code.py proj/proj/resources/__init__.py proj/proj/resources/images/__init__.py proj/proj/resources/images/pic1.png proj/proj/resources/images/pic2.png
Observe cómo guardo todos los recursos en un subpaquete separado.
"code.py"
muestra cómo pkg_resources
se usa para referirse a los objetos de recursos:
from pkg_resources import resource_string, resource_listdir
# Itemize data files under proj/resources/images:
print resource_listdir(''proj.resources.images'', '''')
# Get the data file bytes:
print resource_string(''proj.resources.images'', ''pic2.png'').encode(''base64'')
Si lo ejecuta, obtiene:
[''__init__.py'', ''__init__.pyc'', ''pic1.png'', ''pic2.png''] iVBORw0KGgoAAAANSUhE ...
Si necesita tratar un recurso como un objeto de archivo, use resource_stream()
.
El código que accede a los recursos puede estar en cualquier lugar dentro de la estructura del subpaquete de su proyecto, solo necesita referirse al subpaquete que contiene las imágenes por su nombre completo: proj.resources.images
, en este caso.
Aquí está "setup.py"
:
#!/usr/bin/env python
from setuptools import setup, find_packages
setup(name=''proj'',
packages=find_packages(),
package_data={'''': [''*.png'']})
Advertencia: para probar cosas "localmente", es decir, sin instalar primero el paquete, tendrá que invocar los scripts de prueba desde el directorio que tiene setup.py
. Si está en el mismo directorio que code.py
, Python no sabrá sobre el paquete proj
. Así que cosas como proj.resources
no se resolverán.
@ pycon2009, hubo una presentación sobre distutils y setuptools. Puedes encontrar todos los videos aquí
Despliegue de huevos e implementación en Python - Parte 1
Despliegue de huevos e implementación en Python - Parte 2
Despliegue de huevos e implementación en Python - Parte 3
En estos videos, describen cómo incluir recursos estáticos en su paquete. Creo que es en la parte 2.
Con setuptools, puede definir dependencias, esto le permitiría tener 2 paquetes que usan recursos del 3er paquete.
Setuptools también le brinda una forma estándar de acceder a estos recursos y le permite utilizar rutas de acceso relativas dentro de sus paquetes, lo que elimina la necesidad de preocuparse sobre dónde están instalados sus paquetes.