PEP8には、インポートをファイルの先頭に置くことに関するルールがあります。
インポートは常にファイルの先頭、モジュールのコメントとドキュメント文字列の直後、モジュールのグローバルと定数の前に置かれます。
ただし、特定のケースでは、次のようなことをしたい場合があります。
import sys
sys.path.insert("..", 0)
import my_module
この場合、pep8
コマンドラインユーティリティは私のコードにフラグを立てます:
E402モジュールレベルのインポートがファイルの先頭にありません
sys.path
の変更でPEP8に準拠するための最良の方法は何ですか?
The Hitchhiker's Guide to Python で指定されている プロジェクト構造 に従っているため、このコードがあります。
このガイドでは、tests
フォルダーとは別のmy_module
フォルダーがあり、どちらも同じディレクトリにあることを推奨しています。 tests
からmy_module
にアクセスするには、..
をsys.path
に追加する必要があると思います
多くの場合、プロジェクトのサブディレクトリfoo/tests
にテストのある複数のファイルがありますが、テストしているモジュールはfoo/src
にあります。インポートエラーなしでfoo/tests
からテストを実行するには、次のようなファイルfoo/tests/pathmagic.py
を作成します。
"""Path hack to make tests work."""
import os
import sys
bp = os.path.dirname(os.path.realpath('.')).split(os.sep)
modpath = os.sep.join(bp + ['src'])
sys.path.insert(0, modpath)
すべてのテストファイルで、次に使用します
import pathmagic # noqa
最初のインポートとして。 「noqa」コメントは、pycodestyle
/pep8
が未使用のインポートについて文句を言うのを防ぎます。
インポートが数個しかない場合、それらのimport
行のPEP8を無視できます:
import sys
sys.path.insert("..", 0)
import my_module # noqa: E402
別の回避策があります。
import sys
... all your other imports...
sys.path.insert("..", 0)
try:
import my_module
except:
raise
私は同様の質問に苦労しましたが、受け入れられた答えよりも少しいい解決策を見つけたと思います。
実際のsys.path操作を行うpathmagic
モジュールを作成しますが、 context manager内で変更を行います :
"""Path hack to make tests work."""
import os
import sys
class context:
def __enter__(self):
bp = os.path.dirname(os.path.realpath('.')).split(os.sep)
modpath = os.sep.join(bp + ['src'])
sys.path.insert(0, modpath)
def __exit__(self, *args):
pass
次に、テストファイル(または必要な場所)で、次の操作を行います。
import pathmagic
with pathmagic.context():
import my_module
# ...
このように、flake8/pycodestyleから苦情を受け取らず、特別なコメントを必要とせず、構造は理にかなっているようです。
簡潔にするために、実際に__exit__
ブロック内のパスを元に戻すことを検討してください。ただし、これは遅延インポート(モジュールコードをコンテキストの外に置く場合)で問題を引き起こす可能性があります。
[〜#〜] edit [〜#〜]:別の質問への 回答でもっと簡単なトリックを見た :noqa
コメントを避けるために、インポートの下にassert pathmagic
を追加します。
すでに次のことを試しましたか:
import sys
from importlib import import_module
sys.path.insert("..", 0)
# import module
my_mod = import_module('my_module')
# get method or function from my_mod
my_method = getattr(my_mod , 'my_method')
Pep8に準拠するには、相対/絶対インポートを実行するためにpythonパスにプロジェクトパスを含める必要があります。
これを行うには、次の回答をご覧ください。 PYTHONPATHにディレクトリを永続的に追加