Rutas de archivo relativas en paquetes de Python
-
06-07-2019 - |
Pregunta
¿Cómo hago referencia a un archivo relativamente al directorio de un paquete?
La estructura de mi directorio es:
/foo package1/ resources/ __init__.py package2/ resources/ __init__.py script.py
script.py
importa paquetes package1
y package2
. Aunque los paquetes pueden ser importados por cualquier otro script en el sistema. ¿Cómo debo hacer referencia a recursos dentro, por ejemplo, package1
para asegurarme de que funcione en caso de que os.path.curdir
sea arbitrario?
Solución
Si desea hacer referencia a archivos de la carpeta foo / package1 / resources
, debería usar la variable __file__
del módulo. Dentro de foo / package1 / __ init__.py
:
from os import path
resources_dir = path.join(path.dirname(__file__), 'resources')
Otros consejos
Una manera simple y segura de hacer esto es usar el método resource_filename
de pkg_resources (que se distribuye con setuptools ) así:
from pkg_resources import resource_filename
filepath = resource_filename('package1', 'resources/thefile')
O, si está implementando esto dentro de package1 / ___ init___.py
:
from pkg_resources import resource_filename
filepath = resource_filename(__name__, 'resources/thefile')
Esto le brinda una solución limpia que también es (si no me equivoco) segura para comprimir.
Puede ser seguro para zip y, al mismo tiempo, usar una API conveniente y agradable si usa twisted.python.modules .
Por ejemplo, si tengo un data.txt
con algo de texto y este sample.py
en un directorio:
from twisted.python.modules import getModule
moduleDirectory = getModule(__name__).filePath.parent()
print repr(moduleDirectory.child("data.txt").open().read())
luego importando sample
hará esto:
>>> import sample
'Hello, data!\n'
>>>
Si su módulo está en un directorio regular, getModule (__ name __). filePath
será un FilePath ; si está en un archivo zip, será un ZipPath , que admite la mayoría, pero no todas, de las mismas API.
Esta es una mala idea, porque si su paquete se instaló como huevo comprimido, entonces los recursos pueden no estar disponibles.
Si usa setuptool, no olvide agregar zip_safe = False a la configuración de setup.py.