setuptools: расположение папки данных пакета



Я использую setuptools для распространения моего пакета python. Теперь мне нужно распространять дополнительные файлы данных.



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



чего бы мне хотелось избежать:



/ #root
|- src/
| |- mypackage/
| | |- data/
| | | |- resource1
| | | |- [...]
| | |- __init__.py
| | |- [...]
|- setup.py


что я хотел бы иметь вместо этого:



/ #root
|- data/
| |- resource1
| |- [...]
|- src/
| |- mypackage/
| | |- __init__.py
| | |- [...]
|- setup.py


Я просто не чувствую себя комфортно с таким количеством подкаталогов, если это не важно. Я не могу найти причину, почему я / должен / поместить файлы в каталог пакета. Также громоздко работать с таким количеством вложенных подкаталогов IMHO. Или есть какая-то веская причина, которая оправдывала бы это ограничение?

413   4  

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 и затем либо:

  1. имеет место data передается через файл конфигурации, аргументы командной строки или
  2. вставьте местоположение в свой код 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/.

Я думаю, что вы можете в принципе дать что-нибудь в качестве аргумента *data_files* to setup ().

Comments

    Ничего не найдено.