caminhos de arquivo relativos em pacotes Python
-
06-07-2019 - |
Pergunta
Como faço referência a um arquivo relativamente ao diretório de um pacote?
A minha estrutura de diretório é:
/foo package1/ resources/ __init__.py package2/ resources/ __init__.py script.py
pacotes de importações script.py
package1
e package2
. Embora os pacotes podem ser importados por qualquer outro script no sistema. Como devo fazer referência a recursos dentro, dizer, package1
para garantir que ele iria trabalhar no caso os.path.curdir
é arbitrário?
Solução
Se você quer fazer referência a arquivos do foo/package1/resources
pasta que você gostaria de usar a variável __file__
do módulo. foo/package1/__init__.py
Interior:
from os import path
resources_dir = path.join(path.dirname(__file__), 'resources')
Outras dicas
Uma maneira simples / segura de fazer isso é usando o método resource_filename
de pkg_resources (o qual é distribuído com setuptools ) da seguinte forma:
from pkg_resources import resource_filename
filepath = resource_filename('package1', 'resources/thefile')
Ou, se você está implementando isso dentro package1/___init___.py
:
from pkg_resources import resource_filename
filepath = resource_filename(__name__, 'resources/thefile')
Isto dá-lhe uma solução limpa que é também (se não me engano) zip seguro.
Você pode ser zip-safe e ao mesmo tempo de uso uma boa conveniente API se você usar twisted.python.modules .
Por exemplo, se eu tiver uma data.txt
com algum texto nele e e este sample.py
em um diretório:
from twisted.python.modules import getModule
moduleDirectory = getModule(__name__).filePath.parent()
print repr(moduleDirectory.child("data.txt").open().read())
em seguida, importando sample
vai fazer isso:
>>> import sample
'Hello, data!\n'
>>>
Se o seu módulo está em um diretório regular, getModule(__name__).filePath
será um FilePath ; se for em um arquivo zip, que será um ZipPath , que suporta a maioria, mas não todos, das mesmas APIs.
Esta é uma má idéia, porque, se o pacote foi instalado como ovo zipado, então os recursos podem não estar disponíveis.
Se você usar setuptool, não se esqueça de adicionar zip_safe = false para a configuração setup.py.