Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Например, если у меня есть 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.

Ответ 3

Простой/безопасный способ сделать это - использовать метод resource_filename из pkg_resources (который распространяется с 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.

Ответ 4

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

Если вы используете setuptool, не забудьте добавить zip_safe = False в конфигурацию setup.py.