Данные доступа Python в подкаталоге Package
Я пишу пакет python с модулями, которым необходимо открыть файлы данных в подкаталоге ./data/
. Прямо сейчас у меня есть пути к файлам, жестко закодированным в мои классы и функции. Я хотел бы написать более надежный код, который может получить доступ к подкаталогу, независимо от того, где он установлен в пользовательской системе.
Я пробовал различные методы, но до сих пор мне не повезло. Похоже, что большинство команд "текущего каталога" возвращают каталог системного интерпретатора python, а не каталог модуля.
Кажется, что это должна быть тривиальная, общая проблема. Но я не могу понять это. Отчасти проблема заключается в том, что мои файлы данных не являются .py
файлами, поэтому я не могу использовать функции импорта и т.п.
Любые предложения?
Сейчас мой каталог пакетов выглядит так:
/
__init__.py
module1.py
module2.py
data/
data.txt
Я пытаюсь получить доступ к data.txt
из module*.py
Спасибо!
Ответы
Ответ 1
Для получения пути к пакету можно использовать символ подчеркивания-underscore-file-underscore-underscore (__file__
), например:
import os
this_dir, this_filename = os.path.split(__file__)
DATA_PATH = os.path.join(this_dir, "data", "data.txt")
print open(DATA_PATH).read()
Ответ 2
Стандартный способ сделать это - с пакетами setuptools и pkg_resources.
Вы можете выложить свой пакет в соответствии со следующей иерархией и настроить файл установки пакета, чтобы указать его ваши ресурсы данных в соответствии с этой ссылкой:
http://docs.python.org/distutils/setupscript.html#installing-package-data
Затем вы можете повторно найти и использовать эти файлы, используя pkg_resources, по этой ссылке:
http://peak.telecommunity.com/DevCenter/PkgResources#basic-resource-access
import pkg_resources
DATA_PATH = pkg_resources.resource_filename('<package name>', 'data/')
DB_FILE = pkg_resources.resource_filename('<package name>', 'data/sqlite.db')
Ответ 3
Предоставить решение, работающее сегодня. Определенно используйте этот API, чтобы не изобретать все эти колеса.
Требуется истинное имя файла файловой системы. Яичные яйца будут извлечены в каталог кеша:
from pkg_resources import resource_filename, Requirement
path_to_vik_logo = resource_filename(Requirement.parse("enb.portals"), "enb/portals/reports/VIK_logo.png")
Возвращает читаемый файл-подобный объект для указанного ресурса; это может быть фактический файл, StringIO или какой-либо подобный объект. Поток находится в "двоичном режиме", в том смысле, что любые байты в ресурсе будут считаны как есть.
from pkg_resources import resource_stream, Requirement
vik_logo_as_stream = resource_stream(Requirement.parse("enb.portals"), "enb/portals/reports/VIK_logo.png")
Обнаружение пакетов и доступ к ресурсам с помощью pkg_resources
Ответ 4
Думаю, я преследовал ответ.
Я создаю модуль data_path.py, который я импортирую в свои другие модули, содержащие:
data_path = os.path.join(os.path.dirname(__file__),'data')
И затем я открываю все свои файлы с помощью
open(os.path.join(data_path,'filename'), <param>)
Ответ 5
Вам нужно имя для всего вашего модуля, вам предоставлено дерево каталогов, не перечисляющее эту деталь, для меня это сработало:
import pkg_resources
print(
pkg_resources.resource_filename(__name__, 'data/data.txt')
)
Заметно, что setuptools не разрешает файлы, основанные на совпадении имен с упакованными файлами данных, поэтому вы должны включать префикс data/
, несмотря ни на что. Вы можете использовать os.path.join('data', 'data.txt)
, если вам нужны альтернативные разделители каталогов. Как правило, я не обнаруживаю проблем с совместимостью с жестко закодированными разделителями каталогов стилей unix.