web-dev-qa-db-ja.com

Pythonパッケージ内から(静的)ファイルを読み取る方法は?

Pythonパッケージの中にあるファイルをどのように読むことができますか?

私の状況

ロードするパッケージには、プログラム内からロードするテンプレート(文字列として使用されるテキストファイル)がいくつかあります。しかし、そのようなファイルへのパスを指定するにはどうすればよいですか?

私がファイルを読みたいと想像してください:

package\templates\temp_file

何らかのパス操作?パッケージベースパスの追跡?

62
ronszon

この構造を持っている場合

lidtk
├── bin
│   └── lidtk
├── lidtk
│   ├── analysis
│   │   ├── char_distribution.py
│   │   └── create_cm.py
│   ├── classifiers
│   │   ├── char_dist_metric_train_test.py
│   │   ├── char_features.py
│   │   ├── cld2
│   │   │   ├── cld2_preds.txt
│   │   │   └── cld2wili.py
│   │   ├── get_cld2.py
│   │   ├── text_cat
│   │   │   ├── __init__.py
│   │   │   ├── REAMDE.md   <---------- say you want to get this
│   │   │   └── textcat_ngram.py
│   │   └── tfidf_features.py
│   ├── data
│   │   ├── __init__.py
│   │   ├── create_ml_dataset.py
│   │   ├── download_documents.py
│   │   ├── language_utils.py
│   │   ├── pickle_to_txt.py
│   │   └── wili.py
│   ├── __init__.py
│   ├── get_predictions.py
│   ├── languages.csv
│   └── utils.py
├── README.md
├── setup.cfg
└── setup.py

このコードが必要です:

import pkg_resources

# __in case you're within the package
# - otherwise it would be 'lidtk' in this example as it is the package name
path = 'classifiers/text_cat/REAMDE.md'  # always use slash
filepath = pkg_resources.resource_filename(__name__, path)

「常にスラッシュを使用する」部分についてはあまりよくわかりません。 setuptools から来る可能性があります

また、パスを使用する場合は、Windowsを使用している場合でも、パス区切り文字としてスラッシュ(/)を使用する必要があることに注意してください。 Setuptoolsは、ビルド時にスラッシュを適切なプラットフォーム固有の区切り文字に自動的に変換します

ドキュメントがどこにあるのか疑問に思う場合:

11
Martin Thoma

「10.8。パッケージ内のデータファイルの読み取り」の内容Python Cookbook、David BeazleyとBrian K. Jonesによる第3版の回答。

ここに行きます:

ファイルが次のように編成されたパッケージがあるとします。

mypackage/
    __init__.py
    somedata.dat
    spam.py

ここで、spam.pyファイルがsomedata.datファイルの内容を読み取りたいとします。それを行うには、次のコードを使用します。

import pkgutil
data = pkgutil.get_data(__package__, 'somedata.dat')

結果の変数データは、ファイルの生の内容を含むバイト文字列になります。

Get_data()の最初の引数は、パッケージ名を含む文字列です。直接指定するか、__package__などの特別な変数を使用できます。 2番目の引数は、パッケージ内のファイルの相対名です。必要に応じて、最終ディレクトリがパッケージ内にある限り、標準のUnixファイル名規則を使用して別のディレクトリに移動できます。

このようにして、パッケージをディレクトリ、.Zipまたは.Eggとしてインストールできます。

5
chaokunyang

パッケージ内のすべてのpythonモジュールには__file__属性

次のように使用できます。

import os 
from mypackage

templates_dir = os.path.join(os.path.dirname(mypackage.__file__), 'templates')
template_file = os.path.join(templates_dir, 'template.txt')

Eggリソースの場合: http://peak.telecommunity.com/DevCenter/PythonEggs#accessing-package-resources

3
Zaur Nasibov

eggファイルを使用していると仮定します。抽出されない:

最近のプロジェクトでこれを「解決」しました。ポストインストールスクリプトを使用して、テンプレートをEgg(Zipファイル)からファイルシステムの適切なディレクトリに抽出します。それはで作業するので、私が見つけた最速、最も信頼性の高いソリューションでした__path__[0]間違った時々に(私は名前を思い出すが、していない行くことができる少なくとも一つのライブラリ間のIカム、そのリストの前に何かを追加したことを! )。

また、卵のファイルは、通常、「エッグキャッシュ」と呼ばれる一時的な場所にその場で抽出されます。あなたはたとえば、スクリプトを起動する前に、あるいは後のいずれかで、環境変数を使用して、その場所を変更することができます。

os.environ['PYTHON_Egg_CACHE'] = path

しかし、適切に仕事をするかもしれない pkg_resources あります。

0
Florian