私は最近、人気のあるPythonスタイルチェッカーである pylint のバージョンをアップグレードしました。
それは私のコード全体に弾道を行き渡り、完全なパッケージパスを指定せずに、同じパッケージでモジュールをインポートする場所を指摘しています。
新しいエラーメッセージはW0403です。
W0403:相対インポート%r、%rにする必要があります
パッケージディレクトリに関連するインポートが検出されたときに使用されます。
たとえば、私のパッケージが次のように構成されている場合:
/cake
/__init__.py
/icing.py
/sponge.py
/drink
そして私が書くスポンジパッケージで:
import icing
の代わりに
import cake.icing
このエラーが発生します。
すべてのPylintメッセージが同等に重要であるとは限らず、それらを却下することを恐れないことは理解していますが、そのような慣行がなぜ不十分な考えと見なされるのかは理解できません。
私は誰かが落とし穴を説明できることを望んでいたので、(私が現在計画しているように)この一見誤った警告をオフにするのではなく、コーディングスタイルを改善できました。
import icing
の問題は、それが絶対インポートであるか相対インポートであるかがわからないことです。 icing
は、Pythonのパスにあるモジュール、または現在のモジュールにあるパッケージである可能性があります。これは、ローカルパッケージがpython標準ライブラリパッケージと同じ名前である場合に、非常に煩わしくなります。
暗黙的な相対インポートを完全にオフにするfrom __future__ import absolute_import
を実行できます。 PEP 328 には、あいまいさに関する正当化を含めて記述されています。 Python 3000では暗黙的な相対インポートが完全にオフになっていると思います。
相対インポートは引き続き可能ですが、次のように明示的に行う必要があります。
from . import icing
いくつかの理由があります。
相対インポートは、モジュールを移動すると簡単に壊れます。
パッケージにfoo.bar
、foo.baz
、baz
モジュールがあるとします。 foo.bar
はfoo.baz
をインポートしますが、相対インポートを使用します。
ここで、foo.bar
をbar
に移動すると、モジュールが突然別のbaz
をインポートします。
相対インポートがあいまいです。上記の例でbar
モジュールを移動しなくても、プロジェクトにやってくる新しい開発者は、ルートレベルではなくbaz
が実際にfoo.baz
であることを認識しないことを許される可能性がありますbaz
パッケージ。
絶対インポートにより、使用されているモジュールが明確になります。そしてimport this
が説くように、明示的は暗黙的よりも優れています。
Python 3は暗黙的な相対インポートを完全に無効にしました。インポートは常に絶対として解釈されるようになりました。つまり、上記の例では、import baz
は常に最上位モジュールをインポートします。代わりに明示的なインポート構文を使用する必要があります(from . import baz
)。
例をPython 2から3に移植すると、予期しない問題が発生します。絶対インポートを使用すると、コードの将来性が保証されます。