1. ホーム
  2. python

[解決済み] Python 3を使ったJupyter Notebookで、別のディレクトリにあるモジュールから相対importでローカル関数をインポートする

2022-04-19 18:07:19

質問

以下のようなディレクトリ構造になっています。

meta_project
    project1
        __init__.py
        lib
            module.py
            __init__.py
    notebook_folder
        notebook.jpynb

で作業する場合 notebook.jpynb 関数にアクセスするために相対インポートを使おうとすると function()module.py を使っています。

from ..project1.lib.module import function

以下のようなエラーが発生します。

SystemError                               Traceback (most recent call last)
<ipython-input-7-6393744d93ab> in <module>()
----> 1 from ..project1.lib.module import function

SystemError: Parent module '' not loaded, cannot perform relative import

相対的なインポートを使ってこれを動作させる方法はありますか?

注意:ノートブックサーバーのインスタンスは meta_project ディレクトリにあるので、これらのファイルの情報にアクセスできるはずです。

また、少なくとも元々意図されていたように project1 はモジュールとして考えられておらず、したがって __init__.py ファイルは、単にファイルシステムのディレクトリという意味でした。もし、問題を解決するために、モジュールとして扱って __init__.py ファイル(たとえ空白でも)でも構いませんが、そうすることで問題が解決するわけではありません。

私はこのディレクトリをマシン間で共有しており、相対インポートによってどこでも同じコードを使用することができます、& 私はしばしば迅速なプロトタイピングのためにノートブックを使用するので、絶対パスを一緒にハックすることを含む提案は役に立ちそうにありません。


編集:これは、以下のようなものです。 Python 3 における相対的なインポート は、一般的な Python 3 の相対インポートと、特にパッケージディレクトリ内からのスクリプトの実行について述べています。これは、jupyter notebookの中で、別のディレクトリにあるローカルモジュールの関数を呼び出そうとする作業と関係があり、一般的な側面と特殊な側面の両方を持っています。

解決方法は?

私は、あなたとほぼ同じ例で このノートブック 隣接するモジュールの関数の使い方をDRYに説明したかったからです。

私の解決策は、このようなスニペットをノートブックに追加することで、Pythonに追加モジュールのインポートパスを伝えることでした。

import os
import sys
module_path = os.path.abspath(os.path.join('..'))
if module_path not in sys.path:
    sys.path.append(module_path)

これにより、モジュール階層から目的の関数をインポートすることができます。

from project1.lib.module import function
# use the function normally
function(...)

を追加する必要があることに注意してください。 __init__.py ファイルを プロジェクト1/ lib/ フォルダを作成してください。