web-dev-qa-db-ja.com

Pythonの相対パスからインポートする

クライアントコード用のフォルダー、サーバーコード用のフォルダー、およびそれらの間で共有されるコード用のフォルダーがあります。

Proj/
    Client/
        Client.py
    Server/
        Server.py
    Common/
        __init__.py
        Common.py

Server.pyおよびClient.pyからCommon.pyをインポートするにはどうすればよいですか?

82
Drew

2014年11月編集(3年後):

Python 2.6および3.xは、適切な相対インポートをサポートします。これにより、不正な操作を回避できます。この方法を使用すると、absoluteインポートではなくrelativeインポートを取得していることがわかります。 「..」は、上のディレクトリに移動することを意味します。

from ..Common import Common

警告として、これはモジュールのoutsideからpythonをモジュールとして実行する場合にのみ機能します。例えば:

python -m Proj

元のハッキーな方法

この方法は、実際にはパッケージを実際に「インストール」していない状況で一般的に使用されています。たとえば、Djangoユーザーに人気があります。

Common /をsys.pathに追加できます(パスのリストpythonは、物をインポートするために調べます):

import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'Common'))
import Common

os.path.dirname(__file__)は、現在のpythonファイルが存在するディレクトリを提供します。その後、ディレクトリの 'Common /'に移動し、モジュールの 'Common'をインポートします。

121
Dave

相対的なインポートは行わないでください。

PEP8 から:

パッケージ内インポートの相対インポートは非​​常に推奨されません。

すべてのコードを1つのスーパーパッケージ(つまり、「myapp」)に入れ、クライアント、サーバー、および共通のコードにサブパッケージを使用します。

Update: "Python 2.6および3.xは、適切な相対インポートをサポートしています(...)"。詳細については Daveの回答 をご覧ください。

12
Michał Šrajer

おもしろいことに、私がちょうど出会ったのと同じ問題があり、この仕事は次のようにして得られます。

linuxコマンドlnと組み合わせると、非常にシンプルになります。

1. cd Proj/Client
2. ln -s ../Common ./

3. cd Proj/Server
4. ln -s ../Common ./

そして、ファイルからsome_stuffをインポートする場合:Proj/Common/Common.pyを次のようにファイルにインポートします:Proj/Client/Client.py

# in Proj/Client/Client.py
from Common.Common import some_stuff

そして、同じことがProj/Serverにも当てはまり、setup.pyプロセスでも機能します。 ここで説明したのと同じ質問

7
jacoolee

相対的なインポートを行うことは絶対に問題ありません!ここに小さな 'ol私は何をします:

#first change the cwd to the script path
scriptPath = os.path.realpath(os.path.dirname(sys.argv[0]))
os.chdir(scriptPath)

#append the relative location you want to import from
sys.path.append("../common")

#import your module stored in '../common'
import common.py
6
Gary Beardsley

PYTHONPATHからのデフォルトのインポート方法はすでに「相対」です。 PYTHONPATHはデフォルトで、元のソースファイルのフォルダーとともにいくつかのシステムライブラリにあります。 -mを指定して実行してモジュールを実行すると、現在のディレクトリがPYTHONPATHに追加されます。したがって、プログラムのエントリポイントがProj内にある場合、import Common.Commonの使用はServer.pyとClient.pyの両方で機能するはずです。

相対的なインポートは行わないでください。望みどおりには機能しません。

4