798

次のディレクトリ構造で、PEP 328に従おうとしています。

pkg/
  __init__.py
  components/
    core.py
    __init__.py
  tests/
    core_test.py
    __init__.py

core_test.pyのインポートステートメントがあります

from ..components.core import GameLoopEvents

ただし、実行すると、次のエラーが発生します。

tests$ python core_test.py 
Traceback (most recent call last):
  File "core_test.py", line 3, in <module>
    from ..components.core import GameLoopEvents
ValueError: Attempted relative import in non-package

周りを検索すると、「 __init__.pyでも相対パスが機能しない」と「相対パスからモジュールをインポートする」が見つかりましたが、役に立ちませんでした。

ここに欠けているものはありますか?

4

20 に答える 20

672

Ignacio Vazquez-Abrams の答えを詳しく説明するには:

Python のインポート メカニズム__name__は、現在のファイルに対して相対的に機能します。ファイルを直接実行すると、通常の名前ではなく、"__main__"代わりに名前が付けられます。したがって、相対インポートは機能しません。

Igancio が提案したように、-mオプションを使用して実行できます。スクリプトとして実行することを意図したパッケージの一部がある場合は、この__package__属性を使用して、パッケージ階層内でのファイルの名前をそのファイルに伝えることもできます。

詳細については、 http://www.python.org/dev/peps/pep-0366/を参照してください。

于 2012-07-18T08:26:51.360 に答える
210

import components.core現在のディレクトリを に追加すると、直接使用できますsys.path

if __name__ == '__main__' and __package__ is None:
    from os import sys, path
    sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
于 2013-10-04T21:00:02.010 に答える
31

core_test.py で、次の操作を行います。

import sys
sys.path.append('../components')
from core import GameLoopEvents
于 2017-01-10T17:44:57.223 に答える
11

ユースケースがテストを実行するためのものであり、それがそうであると思われる場合は、次のことができます。テスト スクリプトを as として実行する代わりに、python core_test.pyなどのテスト フレームワークを使用しますpytest。次に、コマンドラインで入力できます

$$ py.test

これにより、ディレクトリでテストが実行されます。これは、@BrenBarn によって指摘された__name__問題を回避します。__main__次に、空の__init__.pyファイルをテスト ディレクトリに配置します。これにより、テスト ディレクトリがパッケージの一部になります。それからあなたはできるようになります

from ..components.core import GameLoopEvents

ただし、テスト スクリプトをメイン プログラムとして実行すると、再び失敗します。したがって、テストランナーを使用してください。多分これは他のテストランナーでも動作しnosetestsますが、私はそれをチェックしていません. お役に立てれば。

于 2015-11-13T17:00:09.563 に答える
3

古いスレッド。__init__.pyファイルにを追加してから、ターゲットで を使用すると正常に動作することがわかりまし__all__= ['submodule', ...]た 。from <CURRENT_MODULE> import *

于 2018-04-18T17:13:32.710 に答える