Как добавить данные пакета рекурсивно в Python setup.py?

У меня есть новая библиотека, которая должна включать в себя множество подпапок с небольшими файлами данных, и я пытаюсь добавить их в виде данных пакета. Представьте, что у меня есть моя библиотека:

library - foo.py - bar.py data subfolderA subfolderA1 subfolderA2 subfolderB subfolderB1 .... 

Я хочу добавить все данные во все подпапки с помощью setup.py, но мне кажется, что мне приходится вручную вводить каждую подпапку (их 100 или около того) и добавить файл инициализации .py. Кроме того, setup.py будет искать эти файлы рекурсивно или мне нужно вручную добавить все их в setup.py, например:

 package_data={ 'mypackage.data.folderA': ['*'], 'mypackage.data.folderA.subfolderA1': ['*'], 'mypackage.data.folderA.subfolderA2': ['*'] }, 

Я могу сделать это со сценарием, но кажется супер-болью. Как я могу достичь этого в setup.py?

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

  • В файле настроек setup.py или pip, как контролировать порядок установки зависимостей пакетов?
  • Почему «python setup.py sdist» создает нежелательные «PROJECT-egg.info» в корневом каталоге проекта?
  • правильный способ найти каталог скриптов из setup.py в Python distutils?
  • Использование setup.py для установки проекта python в качестве службы systemd
  • setup.py проверить, существует ли зависимость библиотеки, отличной от python
  • Задание дополнительных зависимостей в pypi python setup.py
  • pip установить PyQt IOError
  • Как создать колесо Pure-Python
  • 4 Solutions collect form web for “Как добавить данные пакета рекурсивно в Python setup.py?”

    1. Используйте Setuptools вместо distutils.
    2. Используйте файлы данных вместо данных пакета. Для них не требуется __init__.py .
    3. Создайте списки файлов и каталогов, используя стандартный код Python, вместо того, чтобы писать буквально:

       data_files = [] directories = glob.glob('data/subfolder?/subfolder??/') for directory in directories: files = glob.glob(directory+'*') data_files.append((directory, files)) # then pass data_files to setup() 

    Проблема с glob ответом заключается в том, что он делает только так. Т.е. он не является полностью рекурсивным. Проблема с ответом copy_tree заключается в том, что файлы, которые будут скопированы, будут оставлены после удаления.

    Правильное решение является рекурсивным, что позволит вам установить параметр package_data в установочном вызове.

    Я написал этот небольшой метод для этого:

     import os def package_files(directory): paths = [] for (path, directories, filenames) in os.walk(directory): for filename in filenames: paths.append(os.path.join('..', path, filename)) return paths extra_files = package_files('path_to/extra_files_dir') setup( ... packages = ['package_name'], package_data={'': extra_files}, .... ) 

    Вы заметите, что когда вы pip uninstall package_name пакет pip uninstall package_name , вы увидите, что ваши дополнительные файлы перечислены (как отслеживается с пакетом).

    Если у вас нет проблем с тем, что ваш файл setup.py используется грязным, используйте distutils.dir_util.copy_tree .
    Вся проблема в том, как исключить из него файлы.
    Вот какой код:

     import os.path from distutils import dir_util from distutils import sysconfig from distutils.core import setup __packagename__ = 'x' setup( name = __packagename__, packages = [__packagename__], ) destination_path = sysconfig.get_python_lib() package_path = os.path.join(destination_path, __packagename__) dir_util.copy_tree(__packagename__, package_path, update=1, preserve_mode=0) 

    Некоторые примечания :

  • Этот код рекурсивно копирует исходный код в путь назначения.
  • Вы можете использовать одну и ту же setup(...) но используйте copy_tree() чтобы расширить каталог, который вы хотите, на путь установки.
  • Пути установки distutil по умолчанию можно найти в его API .
  • Более подробную информацию о copy_tree () модуле distutils можно найти здесь .
  • Я могу предложить небольшой код для добавления data_files в setup ():

     data_files = [] start_point = os.path.join(__pkgname__, 'static') for root, dirs, files in os.walk(start_point): root_files = [os.path.join(root, i) for i in files] data_files.append((root, root_files)) start_point = os.path.join(__pkgname__, 'templates') for root, dirs, files in os.walk(start_point): root_files = [os.path.join(root, i) for i in files] data_files.append((root, root_files)) setup( name = __pkgname__, description = __description__, version = __version__, long_description = README, ... data_files = data_files, ) 
    Python - лучший язык программирования в мире.