2009-08-13 18 views
135

私たちは、WindowsとLinuxの両方に配備されたコードリポジトリを使用しています。プロジェクト内のモジュールのどれがプロジェクト内の非Pythonリソース(CSVファイルなど)のどれを参照する必要がありますか?Pythonでコードリポジトリを操作する際の相対パスを参照する方法

我々は次のような何かを行う場合は、次のスクリプトは、1つの特定のディレクトリ、またはディレクトリのサブセットから実行された場合にのみが動作する

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

thefile=open('test.csv') 

かを。

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

これが正しいやり方です:私がやりたい何

のようなものがありますか?出来ますか?

答えて

184

現在のファイルパスに関連するファイル名を使用してください。 './my_file'の例:

+3

:絶対パスを使用して

は、最善の解決策である必要があります。 /ここにいくつかのサブディレクトリ がresource_file.csv – olamundo

+0

申し訳ありませんが、ファイルツリーが文字化けしました /Project_Root_dir /python_files_dir /いくつかのより多くのサブディレクトリここ py_file.py /リソース :どのようにあなたは、以下のツリー構造を持っているとき、あなたはそれを解決するのです その最後のメッセージで... 2回目の試み: /Project_Root_dir/python_files_dir/some_subdirs/py_file.pyにファイルがあり、/Project_Root_dir/resources/some_subdirs/resource_file.csvにリソースファイルがあります – olamundo

+22

あなたはjoin(foo、 '..')を使用して親ディレクトリに移動します。したがって、/ root/python_files/module/myfileから、os.path.join(os.path.dirname( '__file__')、 '..'、 '..'、 'resources')を使用してください。 – c089

1

__file__変数でビルドを使用できます。現在のファイルのパスが含まれています。あなたのプロジェクトのルートにあるモジュールにgetBaseOfProjectを実装します。そこに私は__file__のパス部分を取得し、それを返すだろう。この方法は、プロジェクトのどこでも使用できます。

4
import os 
cwd = os.getcwd() 
path = os.path.join(cwd, "my_file") 
f = open(path) 

またos.path.abspath(os.getcwd())を使用してcwdを正規化してみてください。詳細情報here。 、スクリプトへのパスが相対することができますので、

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__ 

変数

は、あなたがそのコードを記述したスクリプトのファイル名を保持している:

+0

'cwd'がモジュールのパスであるユースケースはほとんどありませんが、 – cedbeu

9

は、私はよくこれに似たものを使用しそれでも絶対パスで書かれています。それはいくつかの理由で非常によく動作します

  • パスは絶対的な、しかし、プロジェクトはまだ相対的なコンテナ

で展開することができ

  • まだ相対的である。しかし、あなたはプラットフォームの互換性を監視する必要があります - Windowsの'os.pathsepはUNIXとは異なります。

  • -1

    私はこの答えを考え出す長い時間を費やしたが、私は最終的にそれを得た(そして、それは実際には本当に簡単です):

    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用のディレクトリにあなたのサブフォルダの相対パスを追加します かなり素早く汚いですが、魅力的に機能します:)

    +4

    これは、問題の.pyファイルと同じディレクトリからPythonプログラムを実行している場合にのみ機能します。そして、その場合は、とにかく 'open( '/ your/subfolder/of/choice')'を実行するだけです。 –

    +3

    とOPは、コードはWindowsとLinuxの両方で動作する必要があると述べています。これはできません。 – user183037

    26

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

    の例では、もちろんあなたも

    を使用することができますあなただけのファイル名が必要な場合はmy_data

    の値となり、リソースと読んでバイナリデータを読み込む

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

    だろう

    resource_filename(package_or_requirement, resource_name) 
    

    例:

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

    利点は、eggのようなアーカイブの配布であっても動作することが保証されていることです。

    は、Pythonでhttp://packages.python.org/distribute/pkg_resources.html#resourcemanager-api

    +3

    これは古い答えですが、私の好みの方法はpkg_resourcesを使うのが望ましいですが、圧縮された卵がなくなると、古き良き時代のように '' __file__''を使うだけで害はないのでしょうか? – Pykler

    +0

    これは堅実なアプローチです。卵のコンベンションが去っても、setuptoolsはそうではなく、実行時に卵が作られるgit reposに対してdepsをインストールしている人は多い – deepelement

    3

    を参照してください、パスはほとんどの場合、あなたのプログラムを実行するディレクトリである現在の作業ディレクトリ、を基準にしています。 現在の作業ディレクトリは、モジュールファイルのディレクトリと同じではない可能性が非常に高いため、現在のモジュールファイルに相対的なパスを使用することは常に悪い選択です。私は、リソースのpythonファイルの同じディレクトリにある、またはそのサブディレクトリにいる場合は、このソリューションはのみ動作すると思います

    import os 
    package_dir = os.path.dirname(os.path.abspath(__file__)) 
    thefile = os.path.join(package_dir,'test.cvs') 
    
    関連する問題