Любая функция python для получения корневого каталога "data_files"?

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

В setup.py

from distutils.core import setup
setup(
    ....,
    ....,
    data_files=[('MyApp/CBV', ['myapp/data/CBV/training.cbv', 'myapp/data/CBV/test.cbv'])],
    ....,
    ....,
    )

Результат установки sudo python setup.py

running install
running build
running build_py
running build_scripts
running install_lib
running install_scripts
changing mode of /usr/local/bin/MyApp_trainer to 755
changing mode of /usr/local/bin/MyApp_reference_updater to 755
changing mode of /usr/local/bin/MyApp_predictor to 755
changing mode of /usr/local/bin/reference_updater to 755
running install_data
creating /usr/local/MyApp/CBV
copying MyApp/data/CBV/training.cbv -> /usr/local/MyApp/CBV
copying MyApp/data/CBV/test.cbv -> /usr/local/MyApp/CBV
running install_egg_info
Removing /usr/local/lib/python2.7/dist-packages/MyApp-0.1.0.egg-info
Writing /usr/local/lib/python2.7/dist-packages/MyApp-0.1.0.egg-info

Из наблюдения, использующего приведенный выше результат, "/usr/local" является корневым каталогом "data_files". Кроме жесткого кодирования, есть ли функции Python, которые могут дать мне этот корневой каталог "data_files"?

Ответ 1

По умолчанию при установке пакета от имени root относительные имена каталогов в списке data_files разрешаются либо по значению sys.prefix (для библиотек на чистом python), либо sys.exec_prefix (для библиотек с скомпилированным расширением), поэтому вы можете извлекать свои файлы на основе этого. Qouting из документации distutils:

Если каталог является относительным путем, он интерпретируется относительно префикса установки (Pythons sys.prefix для пакетов на чистом Python, sys.exec_prefix для пакетов, содержащих модули расширения).

Так что для вашего примера вы найдете ваши файлы в os.path.join(sys.prefix, 'MyApp', 'CBV').

Однако было бы лучше использовать расширение setuptools для distutils и использовать модуль ресурсов pkg_resources API для загрузки файлов данных. Он поставляется с setuptools для этой цели. Вы хотите, чтобы ваши файлы данных, включенные в пакет, работали лучше всего. Это означает, что вы не будете использовать data_files, а вместо этого либо перечисляете шаблоны файлов в файле MANIFEST.in и устанавливаете include_package_data=True, либо перечисляете шаблоны файлов в package_data, см. Включение файлов данных в документации по setuptools.

Затем вы можете загрузить такие файлы ресурсов прямо из пакета в строку с resource_string(), например:

from pkg_resources import resource_string

foo_config = resource_string(__name__, 'foo.conf')