次のパッケージ(および作業ディレクトリ)があります。
WorkingDirectory--
|--MyPackage--
| |--__init__.py
| |--module1.py
| |--module2.py
|
|--notebook.ipynb
__init__.py
にあるもの:
import module1
import module2
MyPackageをノートブックにインポートしようとすると:
import MyPackage as mp
ModuleNotFoundError: No module named 'module1'
を取得します。しかし、ノートブックの外でスクリプトを実行すると、インポートは正常に機能します。同じディレクトリにtest.py
を作成し、ノートブックと同じことをすると、インポートは正常に機能します。 __init__.py
(import MyPackage.module1
)で完全修飾名を使用すると、ノートブック内で機能します。
異なるインポート動作の理由は何ですか?
ノートブックの作業ディレクトリがWorkingDirectory
であることを確認しました。
- -更新 - - - - -
正確なエラー:
C:\Users\Me\Documents\Working Directory\MyPackage\__init__.py in <module>()
---> 17 import module1
ModuleNotFoundError: No module named 'module1'
私の問題は、可能な重複とは異なります。
ノートブックはパッケージを見つけることができましたが、モジュールをロードできませんでした。これは、module1
をMyPackage.module1
に置き換えることにより推測され、PATH
に関連する問題ではない可能性があることを示唆しています。
WorkingDirectory
に変更し、そこでサーバーを起動しました。作業ディレクトリは、私のパッケージを含むフォルダである必要があります。
私はこの問題が関連していると確信しており、そこの答えがあなたを助けます: https://stackoverflow.com/a/15622021/7458681
tl; drノートブックサーバーのcwdは、サーバーを起動したベースパスであり、import os os.getcwd()
が実行されていても関係ありません。 import sys sys.path.append("/path/to/your/module/folder")
を使用します。
指定したものと同じ構造のダミーモジュールをいくつか使用して実行しましたが、sys.path
を変更する前は実行されず、実行後には
理由は、_MyPackage/__init__.py
_が現在の作業ディレクトリから実行されるためです。例えば。この場合、WorkingDirectory
から。つまり、インタープリターは_module1
_という名前のモジュールを見つけることができません。これは、モジュールが現在のパッケージディレクトリにもグローバルパッケージディレクトリにも配置されていないためです。
これにはいくつかの回避策があります。たとえば、次のように現在の作業ディレクトリを一時的に上書きできます
_cwd = os.getcwd()
csd = __path__[0]
os.chdir(csd)
_
そして、_import module1
_などのすべてのパッケージ初期化アクションが完了したら、os.chdir(cwd)
を使用して「呼び出し元」の作業ディレクトリを復元します。
たとえば、初期化アクションで例外が発生した場合、作業ディレクトリは復元されないため、これは非常に悪いアプローチです。これを修正するには、_try..except
_ステートメントで遊ぶ必要があります。
別のアプローチは、相対的なインポートを使用することです。詳細については、 documentation を参照してください。
以下は、あなたの例で機能する_MyPackage/__init__.py
_の例です。
_from .module1 import *
_
ただし、ドキュメントを使用した場合よりも経験的に見られる欠点はほとんどありません。たとえば、_import .module1
_のようなものを書くことはできません。
Upd:_import MyPackage
_が通常のpythonコンソールから実行された場合でも、この例外が発生することがわかりました。 IPythonまたはJupyter Notebookからではありません。したがって、これはIPython自体の問題ではないようです。