jupyter notebookで上位階層のモジュールをimportする
jupyter notebookから上位階層にあるモジュールをimportするときに、通常のpythonファイルのようにはいかなかったので、その解決方法を紹介したいと思います。
解決方法としては、以下のコマンドをimportの前に追加してあげれば良いだけです。
import sys sys.path.append('..') #('')の中に探索元のpathを書く
以下、前提やら簡単な説明やらを書いていきます。
前提
以下のような階層を想定して、sample.py, sample.ipynbからhoge.py内のprint_fugaをimportしたいと思います。
|-- utils/ |-- hoge.py |-- examples/ |-- sample.py |-- sample.ipynb
通常のpythonファイルでは
以下のように、sys.path
に探索元のpathを追加してあげることで、importすることができます。
※sys.pathとは探索してくれるpathが格納されているリストのことです。
__file__
は実行場所から実行スクリプトファイル(この場合はsample.py)への相対パスなので、
どの場所からsample.pyを実行しても問題なくimportすることができます。
import sys, os sys.path.append(os.path.join(os.path.dirname(__file__), '..')) from utils.hoge import print_fuga print_fuga()
同じ方法をnotebookで行おうとすると
通常のpythonファイルと同様の方法でnotebook上で実行しようとすると、以下のようなエラーが出てきてしまいます。
jupyter notebookでは、__file__
が定義されていないようですね、、(そのままですが、、)
NameError: name '__file__' is not defined
解決方法
import sys sys.path.append('..') from utils.hoge import print_fuga print_fuga()
これでも良いのかってほどの方法で解決してしまいました。
jupyter notebookは外から呼ばれることを想定されていないので、この方法で良いだろうって感じですね~。
ちなみに、sys.path.append(os.path.join(os.getcwd(), '..'))
とかでも解決できるのですが、一番シンプルな方法にしました。
補足
通常のpythonファイルでsys.path.append('..')
を使ってしまった場合、実行場所と実行スクリプトファイルの場所が異なるときにImport Error
が出てしまうので、注意してください。
jupyter notebookでは、実行場所と実行ファイルの場所が一致しているはずという前提のもと解決しているので、
参考
- Pythonの相対インポートで上位ディレクトリ・サブディレクトリを指定 | note.nkmk.me
- Pythonで実行ファイルの場所(パス)を取得するfile | note.nkmk.me
- 29.1. sys — System-specific parameters and functions — Python 3.6.8 documentation
最後に
解決方法は拍子抜けするほど簡単でした、、
この問題に引っかかって解決するまで20分ぐらい時間がかかった気がするので共有します
はじめてこういうものを書いてみたので慣れていないのですが、こっちの方が良いよ等の意見があればコメント・twitter等でお待ちしております。