Do I always have to restart my kernel in Jupyter Lab when code in a local module changes?

Viewed 2137

When I'm working on a notebook using Jupyter Lab, often times, I put code into a local folder so that I can reuse that code in other notebooks. I typically reference that local module by doing the following.

import os
import sys

sys.path.insert(0, os.path.abspath('.'))

So, if I catch a bug or need to enhance the code and modify the *.py files, I cannot get the new code to load by simply re-running the cell. I have to restart the new kernel to get the new changes. This development cycle is pretty bad, especially when parts of the notebook are computationally expensive to run.

Is there any tip on how to more efficiently code and revise module code alongside a Juypter Lab notebook?

The structure of my code looks like the following.

temp/
├── lib
│   ├── __init__.py
│   ├── misc.py
│   └── utils.py
└── notebook.ipynb

The misc.py has the following code.

def say_hi(name):
    print(f'hi {name}')

The utils.py has the following code.

def say_bye(name):
    print(f'bye bye {name}')

In a cell, I then import a function as follows.

from lib.utils import say_bye

say_bye('john')

Now suppose I change say_bye(), how do I reload the module?

3 Answers

The best way to do this is to use the autoreload magic from IPython:

In [1]: %load_ext autoreload

In [2]: %autoreload 2

In [3]: from foo import some_function

In [4]: some_function()
Out[4]: 42

In [5]: # open foo.py in an editor and change some_function to return 43

In [6]: some_function()
Out[6]: 43

Documentation.

If I understand correctly you are importing your modules and you would like to reload them after making modifications. This can be done using the importlib.reload() function:

import importlib
importlib.reload(my_module) 

The module my_module must have been previously imported in order to be reloaded.

With the guidance of @bb1, I was able to get it to work. It seems I'll have to have a dangling cell above or below all cells (somewhere) with the following code.

import importlib
import sys

_ = importlib.reload(sys.modules['lib'])
_ = importlib.reload(sys.modules['lib.utils'])

If and when I change code in the module, I will have to re-run this cell and the new code takes effect.

If you want, you can inspect the loaded modules with sys.modules.keys().

Related