Относительные пути к файлам в пакетах Python

как ссылаться на файл относительно каталога пакета?

моя структура каталогов:

    /foo
     package1/
      resources/
      __init__.py
     package2/
      resources/
      __init__.py
     script.py

script.py пакеты импорта package1 и package2. Хотя пакеты могут быть импортированы любым другим скриптом в системе. Как я должен ссылаться на ресурсы внутри, скажем,package1 чтобы убедиться, что он будет работать в случае os.path.curdir произвольный?

4 ответов


если вы хотите ссылаться на файлы foo/package1/resources папка, которую вы хотели бы использовать __file__ переменной модуля. Внутри foo/package1/__init__.py:

from os import path
resources_dir = path.join(path.dirname(__file__), 'resources')

простой/безопасный способ сделать это с помощью resource_filename метод (которая распространяется с setuptools) вот так:

from pkg_resources import resource_filename
filepath = resource_filename('package1', 'resources/thefile')

или, если вы реализуете это внутри package1/___init___.py:

from pkg_resources import resource_filename
filepath = resource_filename(__name__, 'resources/thefile')

это дает вам чистое решение, которое также (если я не ошибаюсь) zip safe.


вы можете быть zip-safe и в то же время использовать хороший удобный API, если вы используете витая.питон.модули.

например, если у меня есть data.txt С некоторым текстом в нем и и это sample.py в одном каталоге:

from twisted.python.modules import getModule
moduleDirectory = getModule(__name__).filePath.parent()
print repr(moduleDirectory.child("data.txt").open().read())

затем импортировать sample будет:

>>> import sample
'Hello, data!\n'
>>>

если ваш модуль находится в обычном каталоге,getModule(__name__).filePath будет FilePath; если она в zip файле, это будет ZipPath, который поддерживает большинство, но не все же API.


Это плохая идея, потому что, если ваш пакет был установлен как zipped egg, то ресурсы могут быть недоступны.

Если вы используете setuptool, не забудьте добавить zip_safe=False в setup.py config.