はしくれエンジニアもどきのメモ

情報系技術・哲学・デザインなどの勉強メモ・備忘録です。

Jupyter Notebookファイルをモジュールのようにロードする

jupyter notebookファイルをモジュールのようにロードする

jupyter notebookファイルを 疑似的にpythonモジュールのようにロードして使うメモ.

環境

  • Windows10

    • jupyter 4.3.0

notebookファイルをロード

デフォでnotebookファイルをモジュールのようにロードしてくれる関数はないようだが, ドキュメントに独自実装のexampleが書いてある.

Importing Jupyter Notebooks as Modules — Jupyter Notebook 5.0.0.dev documentation

notebookファイルのロード例

exampleの流れでは,

  1. notebookファイル(.ipynb)のcodeセルのみを読み込むLoderを作る.

  2. notebookファイルを探してLoderを呼ぶFinderを作る.

  3. FinderをhookすることでPythonのPATHの中のnotebookファイルをロードする.

今回はこのexmapleをnbload.pyとして作っておく.

load notebook files

  1. Loader classの作成

    try節の中で.ipynbファイルの中のcode cellのみロードしている.

    
    class NotebookLoader(object):
    """Module Loader for Jupyter Notebooks"""
    
    def __init__(self, path=None):
      self.shell = InteractiveShell.instance()
      self.path = path
    
    def load_module(self, fullname):
    """import a notebook as a module"""
    path = find_notebook(fullname, self.path)
    
    print("importing Jupyter notebook from %s" % path)
    
    # load the notebook object
    with io.open(path, 'r', encoding='utf-8') as f:
        nb = read(f, 4)
    
    # create the module and add it to sys.modules
    # if name in sys.modules:
    #    return sys.modules[name]
    mod = types.ModuleType(fullname)
    mod.__file__ = path
    mod.__loader__ = self
    mod.__dict__['get_ipython'] = get_ipython
    sys.modules[fullname] = mod
    
    # extra work to ensure that magics that would affect the user_ns
    # actually affect the notebook module's ns
    save_user_ns = self.shell.user_ns
    self.shell.user_ns = mod.__dict__
    
    try:
        for cell in nb.cells:
            if cell.cell_type == 'code':
                # transform the input to executable Python
                code = self.shell.input_transformer_manager.transform_cell(
                    cell.source)
                # run the code in themodule
                exec(code, mod.__dict__)
    finally:
        self.shell.user_ns = save_user_ns
    return mod
    
  2. Finder classを作成

    notebookファイルにのみ対してLoaderを使用.

    
    class NotebookFinder(object):
    """Module finder that locates Jupyter Notebooks"""
    def __init__(self):
      self.loaders = {}
    
    def find_module(self, fullname, path=None):
      nb_path = find_notebook(fullname, path)
      if not nb_path:
        return
    
      key = path
      if path:
        # lists aren't hashable
        key = os.path.sep.join(path)
    
      if key not in self.loaders:
        self.loaders[key] = NotebookLoader(path)
        return self.loaders[key]
    
  3. hookを登録

    PythonのPATH内のnotebookファイルに適用できるようFinderを登録 sys.meta_path.append(NotebookFinder())

使い方

example/want_to_load.ipynbを別のノートブックファイルからimport(ロード)する.

  1. nbload.pypythonのPATHが通っているところにあらかじめ置いておく.そしてnbloadimortする.

    import nbload
    

    これで,.ipynbファイルをロードできる.

  2. want_to_load.ipynbの場所がPythonから見えていないimportできないのでPATHを通す.

    sys.path.append("../example/")
    
  3. loadしたいwant_to_load.ipynbが見えるようになるので,importする.

    
    import want_to_load
    

まとめると,ノートブックファイルの先頭に以下を書いておけばいい.


import nbload
sys.path.append("../example/")

import want_to_load