WindowsとLinuxの両方に展開されるコードリポジトリを使用しています(時には異なるディレクトリにあります)。プロジェクト内のモジュールの1つは、プロジェクト内の非Pythonリソース(CSVファイルなど)の1つをどのように参照する必要がありますか?
次のようなことをする場合:
thefile=open('test.csv')
または:
thefile=open('../somedirectory/test.csv')
特定のディレクトリ、またはディレクトリのサブセットからスクリプトが実行される場合にのみ機能します。
私がやりたいことは次のようなものです:
path=getBasePathOfProject()+'/somedirectory/test.csv'
thefile=open(path)
これは正しい方法ですか?出来ますか?
現在のファイルパスに関連するファイル名を使用してみてください。 「./my_file」の例:
fn = os.path.join(os.path.dirname(__file__), 'my_file')
Python 3.4+では、 pathlib も使用できます。
fn = pathlib.Path(__file__).parent / 'my_file'
セットアップツールを使用するか、配布(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")
利点は、Eggのようなアーカイブ配布であっても機能することが保証されていることです。
http://packages.python.org/distribute/pkg_resources.html#resourcemanager-api を参照してください
私はよくこれに似たものを使用します:
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とは異なります。
Pythonでは、パスはcurrent working directoryに関連しています。これはほとんどの場合、プログラムを実行するディレクトリです。 現在の作業ディレクトリはモジュールファイルのディレクトリと同じではない可能性が高いため、現在のモジュールファイルに対する相対パスを使用することは常に悪いことです選択。
絶対パスを使用することが最善の解決策です。
import os
package_dir = os.path.dirname(os.path.abspath(__file__))
thefile = os.path.join(package_dir,'test.cvs')
import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)
また、os.path.abspath(os.getcwd())
を使用してcwd
を正規化しようとします。詳細 こちら 。
__file__
変数でビルドを使用できます。現在のファイルのパスが含まれています。プロジェクトのルートにあるモジュールにgetBaseOfProjectを実装します。そこで、__file__
のパス部分を取得し、それを返します。このメソッドは、プロジェクトのあらゆる場所で使用できます。
ここで少し困惑しました。いくつかのリソースファイルをホイールファイルにパッケージ化し、それらにアクセスしたい。マニフェストファイルを使用してパッケージ化しましたが、サブディレクトリでない限り、pip installはパッケージをインストールしませんでした。これらのシーンショットが役立つことを願っています
├── cnn_client
│ ├── image_preprocessor.py
│ ├── __init__.py
│ ├── resources
│ │ ├── mscoco_complete_label_map.pbtxt
│ │ ├── retinanet_complete_label_map.pbtxt
│ │ └── retinanet_label_map.py
│ ├── tf_client.py
MANIFEST.in
recursive-include cnn_client/resources *
標準のsetup.pyを使用してウィールを作成しました。 pipはwheelファイルをインストールしました。インストール後、リソースがインストールされているかどうかを確認しました。彼らです
ls /usr/local/lib/python2.7/dist-packages/cnn_client/resources
mscoco_complete_label_map.pbtxt
retinanet_complete_label_map.pbtxt
retinanet_label_map.py
Tfclient.pyでこれらのファイルにアクセスします。 from
templates_dir = os.path.join(os.path.dirname(__file__), 'resources')
file_path = os.path.join(templates_dir, \
'mscoco_complete_label_map.pbtxt')
s = open(file_path, 'r').read()
そしてそれは動作します。