204

私たちは、Windows と Linux の両方に (場合によっては異なるディレクトリに) デプロイされるコード リポジトリを使用しています。プロジェクト内のモジュールの 1 つは、プロジェクト内の非 Python リソース (CSV ファイルなど) の 1 つをどのように参照する必要がありますか?

次のようなことをすると:

thefile = open('test.csv')

また:

thefile = open('../somedirectory/test.csv')

スクリプトが 1 つの特定のディレクトリ、またはディレクトリのサブセットから実行された場合にのみ機能します。

私がやりたいことは次のようなものです:

path = getBasePathOfProject() + '/somedirectory/test.csv'
thefile = open(path)

出来ますか?

4

9 に答える 9

280

現在のファイル パスに相対的なファイル名を使用してみてください。「./my_file」の例:

fn = os.path.join(os.path.dirname(__file__), 'my_file')

Python 3.4 以降では、 pathlibも使用できます。

fn = pathlib.Path(__file__).parent / 'my_file'
于 2009-08-13T09:27:28.263 に答える
48

セットアップ ツールまたは配布 (setup.py インストール) を使用している場合、これらのパッケージ化されたリソースにアクセスする "正しい" 方法は、package_resources を使用しているようです。

あなたの場合、例は次のようになります

import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")

もちろん、どちらがリソースを読み取り、読み取ったバイナリデータは my_data の値になります

ファイル名だけが必要な場合は、使用することもできます

resource_filename(package_or_requirement, resource_name)

例:

resource_filename("MyPackage","foo.dat")

利点は、タマゴのようなアーカイブ ディストリビューションであっても動作することが保証されていることです。

http://packages.python.org/distribute/pkg_resources.html#resourcemanager-apiを参照してください

于 2012-02-07T14:24:07.670 に答える
15

私はよくこれに似たものを使用します:

import os
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), 'datadir'))

# if you have more paths to set, you might want to shorten this as
here = lambda x: os.path.abspath(os.path.join(os.path.dirname(__file__), x))
DATA_DIR = here('datadir') 

pathjoin = os.path.join
# ...
# later in script
for fn in os.listdir(DATA_DIR):
    f = open(pathjoin(DATA_DIR, fn))
    # ...

変数

__file__

そのコードを書き込むスクリプトのファイル名を保持するため、スクリプトに相対的なパスを作成できますが、絶対パスを使用して記述されます。それはいくつかの理由で非常にうまく機能します:

  • パスは絶対的ですが、それでも相対的です
  • プロジェクトは引き続き相対コンテナにデプロイできます

ただし、プラットフォームの互換性に注意する必要があります。Windowsのos.pathsepはUNIXとは異なります。

于 2009-08-13T12:11:19.423 に答える
6
import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)

cwdまた、を使用して正規化しようとしますos.path.abspath(os.getcwd())。詳細はこちら

于 2009-08-13T09:40:27.410 に答える
2

__file__組み込み変数を使用できます。現在のファイルのパスが含まれています。プロジェクトのルートにあるモジュールに getBaseOfProject を実装します。そこでパス部分を取得し、__file__それを返します。このメソッドは、プロジェクトのどこでも使用できます。

于 2009-08-13T09:28:40.977 に答える
0

さまざまな場所にデプロイするコードがあると言うので、python エコシステムを使用して、ファイルのみに限定されないリソースを配布する必要があります。また、zip アーカイブ内のファイルへのアクセスもサポートしているため、面倒な作業が不要になります。

以前は、これは from で処理さpkg_resourcessetuptoolsていましたが、より多くのツールが出現するにつれて、エコシステムは変化しました。Python 3.7 以降では、importlib.resourcesを使用する必要があります。

import importlib.resources
with importlib.resources.open_text('mypackage.somedirectory','text.csv') as f:
    print(f.read()) # or whatever

ただし、インストーラーにパッケージ リソースを含めるように指示する必要もあります。そうしpip install mypackageないと、データ ファイルがバンドルされません。

それを行うには多くの方法がありますが、それを行う1つの方法は追加することです

[options.package_data]
mypackage = 
    "somedirectory/*.csv"

あなたにsetup.cfgsetup.pyまたはを使用する場合には、同等のアプローチがありますpyproject.tomlsetuptools ホームページで、より完全なアカウントを入手できます。

于 2021-10-20T13:41:37.700 に答える
-5

私はこれに対する答えを見つけるのに長い時間を費やしましたが、最終的にそれを手に入れました (そして、それは実際には非常に簡単です):

import sys
import os
sys.path.append(os.getcwd() + '/your/subfolder/of/choice')

# now import whatever other modules you want, both the standard ones,
# as the ones supplied in your subfolders

これにより、サブフォルダーの相対パスが、Python が検索するディレクトリに追加されます。これは非常に迅速で汚いですが、魅力のように機能します :)

于 2011-02-02T12:43:48.627 に答える