your programing

setuptools : 패키지 데이터 폴더 위치

lovepro 2020. 10. 10. 10:47
반응형

setuptools : 패키지 데이터 폴더 위치


저는 setuptools를 사용하여 파이썬 패키지를 배포합니다. 이제 추가 데이터 파일을 배포해야합니다.

setuptools 문서에서 수집 한 내용에서 패키지 디렉토리에 데이터 파일이 있어야합니다. 그러나 루트 디렉토리의 하위 디렉토리에 데이터 파일을 두는 것이 좋습니다.

내가 피하고 싶은 것 :

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

대신 갖고 싶은 것 :

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

필수가 아니라면 너무 많은 하위 디렉터리가있는 것이 편하지 않습니다. 이유를 찾지 못했습니다. 패키지 디렉토리에 파일을 넣는 이유를 / have /합니다. 너무 많은 중첩 하위 디렉토리 IMHO로 작업하는 것도 번거 롭습니다. 아니면이 제한을 정당화 할만한 합당한 이유가 있습니까?


옵션 1 : 패키지 데이터로 설치

Python 패키지의 루트 내에 데이터 파일을 배치 할 때의 주요 이점은 Windows, Mac, Linux, 일부 모바일 플랫폼 또는 Egg 내부와 같은 사용자 시스템에서 파일이 어디에 있는지 걱정하지 않아도된다는 것입니다. 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

프로젝트가 Egg로 설치되면 경로 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'])
        ]
    )

업데이트 됨 : Python 파일을 재귀 적으로 grep하는 셸 함수의 예 :

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

samplebias 답변에 설명 된 문제를 방지하려면 데이터를 package_data로 설치해야하지만 파일 구조를 유지하려면 setup.py에 추가해야합니다.

try:
    os.symlink('../../data', 'src/mypackage/data')
    setup(
        ...
        package_data = {'mypackage': ['data/*']}
        ...
    )
finally:
    os.unlink('src/mypackage/data')

This way we create the appropriate structure "just in time", and mantain our source tree organized.

To access such data files within your code, you 'simply' use:

data = resource_filename(Requirement.parse("main_package"), 'mypackage/data')

I still don't like having to specify 'mypackage' in the code, as the data could have nothing to do necessarally with this module, but i guess its a good compromise.


I think that you can basically give anything as an argument *data_files* to setup().

참고URL : https://stackoverflow.com/questions/4519127/setuptools-package-data-folder-location

반응형