Pythonプロジェクトでのリソースの管理
-
22-09-2019 - |
質問
多くの非コードファイルを使用しているPythonプロジェクトがあります。現在、これらはすべて画像ですが、将来他の種類のファイルを使用する可能性があります。これらのファイルを保存して参照するための良いスキームは何でしょうか?
メインディレクトリにフォルダを「リソース」するだけであることを考えましたが、問題があります。一部の画像は、私のプロジェクトのサブパッケージ内から使用されています。これらの画像をそのように保存すると、カップリングにつながります。これは不利です。
また、現在のディレクトリが何であるかについて独立したこれらのファイルにアクセスする方法が必要です。
解決
使用したい場合があります pkg_resources
付属のライブラリ setuptools
.
たとえば、私は簡単な小さなパッケージを作りました "proj"
私が使用するリソース組織スキームを説明するために:
proj/setup.py proj/proj/__init__.py proj/proj/code.py proj/proj/resources/__init__.py proj/proj/resources/images/__init__.py proj/proj/resources/images/pic1.png proj/proj/resources/images/pic2.png
すべてのリソースを別のサブパッケージに保持する方法に注目してください。
"code.py"
ショーショー pkg_resources
リソースオブジェクトを参照するために使用されます。
from pkg_resources import resource_string, resource_listdir
# Itemize data files under proj/resources/images:
print resource_listdir('proj.resources.images', '')
# Get the data file bytes:
print resource_string('proj.resources.images', 'pic2.png').encode('base64')
実行すると、次のようになります。
['__init__.py', '__init__.pyc', 'pic1.png', 'pic2.png'] iVBORw0KGgoAAAANSUhE ...
リソースをFileObjectとして扱う必要がある場合は、使用してください。 resource_stream()
.
リソースにアクセスするコードは、プロジェクトのサブパッケージ構造内のどこにでもある場合があります。フルネームで画像を含むサブパッケージを参照するだけです。 proj.resources.images
, 、 この場合。
これがそうです "setup.py"
:
#!/usr/bin/env python
from setuptools import setup, find_packages
setup(name='proj',
packages=find_packages(),
package_data={'': ['*.png']})
警告:「ローカル」、つまりパッケージを最初にインストールしたことをテストするには、ディレクトリからテストスクリプトを呼び出す必要があります。 setup.py
. 。あなたが同じディレクトリにいる場合 code.py
, 、Pythonは知りません proj
パッケージ。だから proj.resources
解決しません。
他のヒント
各サブパッケージに必要な個別の「リソース」フォルダーをいつでも使用でき、使用できます。 os.path
これらに到達する機能 __file__
サブパッケージの値。私が意味することを説明するために、私は次のことを作成しました __init__.py
3つの場所にファイルします。
c:\temp\topp (top-level package) c:\temp\topp\sub1 (subpackage 1) c:\temp\topp\sub2 (subpackage 2)
これが次のとおりです __init__.py
ファイル:
import os.path
resource_path = os.path.join(os.path.split(__file__)[0], "resources")
print resource_path
c: temp workでは、次のようにアプリ、topapp.pyを作成します。
import topp
import topp.sub1
import topp.sub2
これにより、を使用してアプリケーションが再現されます topp
パッケージとサブパッケージ。それから私はそれを実行します:
C:\temp\work>topapp Traceback (most recent call last): File "C:\temp\work\topapp.py", line 1, in import topp ImportError: No module named topp
それは予想通りです。 PythonPathを設定して、パスをパスに配置することをシミュレートします。
C:\temp\work>set PYTHONPATH=c:\temp C:\temp\work>topapp c:\temp\topp\resources c:\temp\topp\sub1\resources c:\temp\topp\sub2\resources
ご覧のとおり、リソースパスは、パス上の実際の(サブ)パッケージの位置に正しく解決されました。
アップデート: ここ関連するPy2exeドキュメント。
@ pycon2009、distutilsとsetuptoolsに関するプレゼンテーションがありました。ここですべてのビデオを見つけることができます
これらのビデオでは、パッケージに静的リソースを含める方法について説明しています。パート2にあると思います。
SetUptoolsを使用すると、依存を定義できます。これにより、3番目のパッケージからリソースを使用する2つのパッケージを使用できます。
Setuptoolsは、これらのリソースにアクセスする標準的な方法を提供し、パッケージ内の相対パスを使用できるようにするため、パッケージがどこにインストールされているかを心配する必要性がなくなります。