53

次のディレクトリがあります。

mydirectory
├── __init__.py
├── file1.py 
└── file2.py

file1.py で定義された関数 f があります。

もし、file2.py で、私が

from .file1 import f

次のエラーが表示されます。

SystemError: 親モジュール '' がロードされていないため、相対インポートを実行できません

なんで?そして、それを機能させる方法は?

4

4 に答える 4

45

パッケージ内のモジュールを実行可能ファイルとして起動することは、悪い習慣です。

何かを開発するときは、他のプログラムによってインポートされることを意図したライブラリを構築するため、そのサブモジュールを直接実行することを許可する意味があまりないか、実行可能ファイルを構築します。この場合、それを一部にする理由はありませんパッケージの。

setup.pyこれが、パッケージとスクリプトを区別する理由です。site-packagesスクリプトが/usr/bin(または OS によっては同様の場所) の下にインストールされる間、パッケージは下に移動します。

したがって、次のレイアウトを使用することをお勧めします。

/
├── mydirectory
|    ├── __init__.py
|    ├── file1.py 
└── file2.py

ライブラリを使用したい他のコードと同じようにfile2.pyインポートし、絶対インポートを使用します。file1.pymydirectory

from mydirectory.file1 import f

プロジェクトのスクリプトを作成するときは、パッケージとスクリプトとしてsetup.pyリストするだけで、すべてが機能します。いじる必要はありません。mydirectoryfile2.pysys.path

何らかの理由で、実際にパッケージのサブモジュールを実際に実行したい場合は、-mスイッチを使用するのが適切な方法です。

python -m mydirectory.file1

これにより、パッケージ全体が読み込まれ、モジュールがスクリプトとして実行され、相対インポートが成功します。

私は個人的にこれを行うことを避けたいと思います。また、多くの人があなたがこれを行うことができることさえ知らず、最終的にあなたと同じエラーが発生し、パッケージが壊れていると考えているためです.


現在受け入れられている回答については、同じディレクトリにあるため機能するため、暗黙的な相対インポートを使用する必要があると述べています。from file1 import f

これは間違っています!

  • 暗黙の相対インポートが許可されていない python3 では機能せず、たまたまモジュールをインストールした場合は確実に壊れます(file1モジュールの代わりにインポートされるためです!)。
  • 動作する場合でも、パッケージfile1の一部として表示されません。mydirectoryこれ問題になる可能性があります。

    たとえば、file1を使用する場合pickle、パッケージの名前は、データの適切なロード/アンロードにとって重要です。

于 2015-10-18T06:42:39.150 に答える
23

file1とは同じディレクトリにあるためfile2、ファイルを用意する必要さえありません__init__.py。スケールアップする場合は、そのままにしておいてください。

同じディレクトリ内のファイルに何かをインポートするには、次のようにします

from file1 import f

.file1つまり、同じディレクトリにあるため、相対パスを指定する必要はありません。

アプリケーション全体を実行するメイン関数、スクリプト、またはその他のものが別のディレクトリにある場合は、実行されている場所に対してすべてを相対的にする必要があります。

于 2013-05-19T17:42:34.330 に答える
0
myproject/

mypackage
├── __init__.py
├── file1.py
├── file2.py 
└── file3.py

mymainscript.py

あるファイルから別のファイルにインポートする例

#file1.py
from myproject import file2
from myproject.file3 import MyClass

パッケージの例をメインスクリプトにインポートする

#mymainscript.py
import mypackage

https://docs.python.org/3/tutorial/modules.html#packages

https://docs.python.org/3/reference/import.html#regular-packages

https://docs.python.org/3/reference/simple_stmts.html#the-import-statement

https://docs.python.org/3/glossary.html#term-import-path

変数 sys.path は、モジュールのインタープリターの検索パスを決定する文字列のリストです。環境変数 PYTHONPATH から取得されたデフォルト パスに初期化されるか、または PYTHONPATH が設定されていない場合は組み込みのデフォルトから取得されます。標準のリスト操作を使用して変更できます。

import sys
sys.path.append('/ufs/guido/lib/python')
sys.path.insert(0, '/ufs/guido/myhaxxlib/python')

先頭に挿入すると、名前の競合が発生した場合に、パスが他のパス (組み込みのものであっても) よりも先に検索されることが保証されるという利点があります。

于 2014-12-17T15:27:06.767 に答える