web-dev-qa-db-ja.com

Pythonモジュールの絶対的インポートと明示的相対インポート

Pythonアプリケーションでパッケージをインポートする好ましい方法について疑問に思っています。このようなパッケージ構造があります。

project.app1.models
project.app1.views
project.app2.models

project.app1.viewsインポートproject.app1.modelsおよびproject.app2.models。これを行うには、2つの方法があります。

絶対インポートの場合:

import A.A
import A.B.B

または Python 2.5 with PEP 328 :で紹介されているように、明示的な相対インポートを使用します。

# explicit relative
import ..A
import .B

これを行うための最もPython的な方法は何ですか?

72
Daniel Hepper

絶対輸入。 PEP 8から:

パッケージ内インポートの相対インポートは非​​常に推奨されません。すべてのインポートに常に絶対パッケージパスを使用します。 PEP 328 [7]はPython 2.5で完全に実装されていますが、明示的な相対インポートのスタイルは積極的に推奨されていません。

明示的な相対インポートはニース言語の機能(推測)ですが、絶対インポートほど明示的ではありません。より読みやすい形式は次のとおりです。

import A.A
import A.B.B

特に、いくつかの異なる名前空間をインポートする場合。パッケージ内からのインポートを含むよく書かれたプロジェクト/チュートリアルを見ると、通常はこのスタイルに従います。

あなたがより明確にするために取るいくつかの余分なキーストロークは、他の人(そしておそらくあなた)があなたの名前空間を理解しようとしているときに特に時間を節約します(特に3.xに移行する場合、名前が変更されました)。

42
Rafe Kettler

Pythonの相対的なインポートは強く推奨されなくなりましたが、その場合はabsolute_importの使用を強くお勧めします。

この議論 Guido自身を引用してください:

「これはほとんど歴史的ではありませんか?新しい相対インポート構文が実装されるまで、相対インポートにはさまざまな問題がありました。短期的な解決策はそれらを使用しないことを推奨することでした。長期的な解決策は明確な構文を実装することでした。反推奨を撤回する時です。もちろん、船外に出ることなく、私はまだ彼らに後天的な味を感じています。しかし、彼らは彼らの場所を持っています。」

OPは PEP 328 を正しくリンクします:

いくつかのユースケースが提示されましたが、その中で最も重要なのは、サブパッケージを編集せずに大きなパッケージの構造を再配置できることです。さらに、パッケージ内のモジュールは、相対的なインポートなしでは簡単にインポートできません。

また、ほとんど重複した質問を参照してください Pythonで相対インポートを使用するタイミングまたは理由

もちろん、それはまだ好みの問題として残っています。相対的なインポートを使用するとコードを簡単に移動できますが、予期せずに問題が発生する可能性もあります。インポートの名前を変更することはそれほど難しくありません。

PEP 328の新しい動作を強制するには、次を使用します。

from __future__ import absolute_import

この場合、暗黙的な相対インポートはできなくなります(たとえば、import localfileは機能しなくなり、from . import localfileのみが機能します)。クリーンで将来性のある動作のために、absolute_importを使用することをお勧めします。

重要な注意点は、 PEP 338 および PEP 366 のため、相対インポートにはpythonファイルをモジュールとしてインポートする必要がある-あなたが相対的なインポートがあるfile.pyを実行できないか、ValueError: Attempted relative import in non-packageを取得します。

最適なアプローチを評価する際には、この制限を考慮する必要があります。 Guidoはどのような場合でもモジュールからスクリプトを実行することに反対です。

私はこれと、__ main__機構の他の提案された調整について-1です。唯一のユースケースは、たまたまモジュールのディレクトリ内にあるスクリプトを実行することであるようです。これは常にアンチパターンと見なされてきました。私の考えを変えさせるには、そうではないことを私に納得させる必要があります。

この問題に関する徹底的な議論はSOにあります。再。 Python 3これは非常に包括的なものです:

  • Python の相対インポート
111
Stefano

相対インポートでは、後で数十の内部インポートを変更せずにパッケージの名前を自由に変更できるだけでなく、循環インポートや名前空間パッケージなどが関係する特定の問題の解決にも成功しました。Python "back to the top"は、トップレベルの名前空間から次のモジュールの検索を開始します。

30
Brandon Rhodes