56

多くの非コードファイルを使用しているPythonプロジェクトがあります。現在、これらはすべて画像ですが、将来的には他の種類のファイルを使用する可能性があります。これらのファイルを保存および参照するための適切なスキームは何でしょうか?

メインディレクトリに「resources」フォルダを作成することを検討しましたが、問題があります。一部の画像は、私のプロジェクトのサブパッケージ内から使用されています。これらの画像をそのように保存すると、結合が発生しますが、これは欠点です。

また、現在のディレクトリに依存しないこれらのファイルにアクセスする方法が必要です。

4

4 に答える 4

63

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..。

リソースをファイルオブジェクトとして扱う必要がある場合は、を使用します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。と同じディレクトリにいる場合、Pythonはパッケージcode.pyについて認識しません。projしたがって、のようなものproj.resourcesは解決されません。

于 2009-09-08T22:22:05.287 に答える
6

サブパッケージごとに、それを必要とする個別の「リソース」フォルダーをいつでも持つことができ、関数を使用して、サブパッケージの値os.pathからこれらにアクセスできます。__file__私が何を意味するかを説明するために、次の__init__.pyファイルを3つの場所に作成しました。

c:\ temp \ topp(トップレベルパッケージ)
c:\ temp \ topp \ sub1(サブパッケージ1)
c:\ temp \ topp \ sub2(サブパッケージ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
トレースバック(最後の最後の呼び出し):
  ファイル"C:\ temp \ work \ topapp.py"、1行目
    toppをインポートする
ImportError: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のドキュメントは次のとおりです。

于 2009-09-08T18:50:26.183 に答える
6

これを行う新しい方法は、を使用することimportlibです。3.7より前のPythonバージョンの場合、依存関係を追加して、次のimportlib_resourcesようなことを行うことができます。

from importlib_resources import files


def get_resource(module: str, name: str) -> str:
    """Load a textual resource file."""
    return files(module).joinpath(name).read_text(encoding="utf-8")

リソースがfoo/resourcesサブモジュール内にある場合は、次get_resourceのように使用します

resource_text = get_resource('foo.resources', 'myresource')
于 2020-10-23T16:03:30.220 に答える
1

@ pycon2009、distutilsとsetuptoolsに関するプレゼンテーションがありました。あなたはここですべてのビデオを見つけることができます

PythonでのEggsとBuildoutのデプロイ-パート1

PythonでのEggsとBuildoutのデプロイ-パート2

PythonでのEggsとBuildoutのデプロイ-パート3

これらのビデオでは、パッケージに静的リソースを含める方法について説明しています。パート2だと思います。

setuptoolsを使用すると、依存関係を定義できます。これにより、3番目のパッケージのリソースを使用する2つのパッケージを作成できます。

Setuptoolsは、これらのリソースにアクセスするための標準的な方法も提供し、パッケージ内で相対パスを使用できるようにします。これにより、パッケージがインストールされている場所について心配する必要がなくなります。

于 2009-09-24T16:16:28.443 に答える