1. ホーム
  2. python

[解決済み] setuptools: パッケージデータのフォルダの場所

2022-11-04 01:49:15

質問

私はpythonパッケージを配布するためにsetuptoolsを使用しています。今、私は追加のデータファイルを配布する必要があります。

setuptoolsのドキュメントから私が収集したところでは、私はパッケージディレクトリの中に私のデータファイルを持っている必要があります。しかし、私はむしろルートディレクトリのサブディレクトリの中に私のデータファイルを持つことを望みます。

私が避けたいと思うこと。

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

代わりに欲しいもの

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

必須でないなら、これほど多くのサブディレクトリを持つことに違和感を覚えます。なぜパッケージディレクトリの中にファイルを置かなければならないのか、その理由を見つけることができません。また、IMHOでは、これほど多くのネストされたサブディレクトリで作業するのは面倒だと思います。あるいは、この制限を正当化するような良い理由があるのでしょうか?

どのように解決するのですか?

オプション1:パッケージデータとしてインストールする

データファイルをPythonパッケージのルート内に配置する主な利点は、ファイルがユーザーのOSのどこに置かれるかを気にする必要がないことです。 データファイルをPythonパッケージのルート内に配置する主な利点は、ファイルがユーザーのシステムのどこに置かれるかを気にする必要がなくなることです。 Windows、Mac、Linux、モバイル プラットフォーム、または Egg の内部などです。あなたは ディレクトリを見つけることができます。 data ディレクトリを見つけることができます。

例えば、このようなプロジェクトのレイアウトがあった場合。

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']}