setuptools: расположение папки данных пакета
Я использую setuptools для распространения моего пакета python. Теперь мне нужно распространять дополнительные файлы данных.
из того, что я собрал из документации setuptools, мне нужно иметь мои файлы данных внутри каталога пакета. Однако я бы предпочел, чтобы мои файлы данных находились внутри подкаталога в корневом каталоге.
чего бы мне хотелось избежать:
/ #root
|- src/
| |- mypackage/
| | |- data/
| | | |- resource1
| | | |- [...]
| | |- __init__.py
| | |- [...]
|- setup.py
что я хотел бы иметь вместо этого:
/ #root
|- data/
| |- resource1
| |- [...]
|- src/
| |- mypackage/
| | |- __init__.py
| | |- [...]
|- setup.py
Я просто не чувствую себя комфортно с таким количеством подкаталогов, если это не важно. Я не могу найти причину, почему я / должен / поместить файлы в каталог пакета. Также громоздко работать с таким количеством вложенных подкаталогов IMHO. Или есть какая-то веская причина, которая оправдывала бы это ограничение?
4 ответов:
Вариант 1: установить, как данные пакета
основное преимущество размещения файлов данных внутри корня вашего пакета Python это позволяет не беспокоиться о том, где файлы будут жить на пользователя система, которая может быть Windows, Mac, Linux, некоторые мобильные платформы, или внутри яйца. Вы можете всегда находите каталог
dataотносительно вашего корня пакета Python, независимо от того, где и как он установлен.например, если у меня есть проект макет вроде так:
project/ foo/ __init__.py data/ resource1/ foo.txtвы можете добавить функцию
__init__.pyнайти абсолютный путь к данным файл:import os _ROOT = os.path.abspath(os.path.dirname(__file__)) def get_data(path): return os.path.join(_ROOT, 'data', path) print get_data('resource1/foo.txt')выходы:
/Users/pat/project/foo/data/resource1/foo.txtпосле установки проекта в виде яйца путь к
dataизменится, но код не нужно менять:/Users/pat/virtenv/foo/lib/python2.6/site-packages/foo-0.0.0-py2.6.egg/foo/data/resource1/foo.txt
Вариант 2: установить в определенном месте
альтернативой было бы разместить ваши данные вне пакета Python и затем либо:
- имеет место
dataпередается через файл конфигурации, аргументы командной строки или- вставьте местоположение в свой код Python.
это гораздо менее желательно, если вы планируете распространять свой проект. Если вы действительно хотите сделать это, вы можете установить свой
dataвезде, где вы хотите на целевой системе, указав место назначения для каждой группы файлов, передавая в списке кортежи:from setuptools import setup setup( ... data_files=[ ('/var/data1', ['data/foo.txt']), ('/var/data2', ['data/bar.txt']) ] )Обновлено: пример функции оболочки для рекурсивно grep Python файлов:
atlas% function grep_py { find . -name '*.py' -exec grep -Hn $* {} \; } atlas% grep_py ": \[" ./setup.py:9: package_data={'foo': ['data/resource1/foo.txt']}
Я думаю, что нашел хороший компромисс, который позволит вам сохранить следующую структуру:
/ #root |- data/ | |- resource1 | |- [...] |- src/ | |- mypackage/ | | |- __init__.py | | |- [...] |- setup.pyвы должны установить данные как package_data, чтобы избежать проблем, описанных в ответе samplebias, но для того, чтобы сохранить структуру файла, которую вы должны добавить в свой setup.py:
try: os.symlink('../../data', 'src/mypackage/data' setup( ... package_data = {'mypackage': ['data/*']} ... ) finally: os.unlink('src/mypackage/data')таким образом, мы создаем соответствующую структуру "как раз вовремя" и сохраняем наше исходное дерево организованным.
доступ к таким файлам данных в коде просто использовать:
data = resource_filename(Requirement.parse("main_package"), 'mypackage/data')мне все еще не нравится указывать "mypackage" в коде, так как данные не могут иметь ничего общего с этим модулем, но я думаю, что это хороший компромисс.
Я использую setuptools для создания собственных пакетов ОС, таких как RPM и DEBs. Макет проекта, который я использую.
<project>/ lib/ -> .../lib/pythonX/site-packages/ bin/ -> .../bin/ etc/ -> /etc/ doc/ man/ -> .../man/man1/ share/ -> .../share/doc/<project>/мой
setup.pyфайл выполняет соответствующее сопоставление, как указано выше. Я нахожу этот макет идеальным для python. Они пакеты производятся перемещаются, но по умолчанию будет идти под/usr/local/.
Comments