When doing data analysis or experimentation with Jupyter notebook, it is often the case that you want to import a specific cell of another notebook that defines a class for analysis. Here are two ways that might work.
The easiest way is to use the magic command %% writefile
. The contents of the cell are copied to filename
by setting %% writefile filename
at the beginning of the cell. All you have to do now is import the filename
from another notebook.
Cell you want to read from another notebook
%%writefile hoge.py
class Hoge:
def __init__(self):
print('Hello from Hoge')
Read and use the contents of other output notebook cells
import hoge
x = hoge.Hoge()
Official says, "Everyone wants to do it, and they don't have to worry about it with just a public API. If you are saying "You can do it!" ~~, I want you to be able to do it with just one command ~~, so I will make it myself by referring to the linked code [^ t dual].
[^ tdual]: @tdual wrote article about the contents of the link. After investigating, the code published in @ tdual's article (that is, the officially introduced code) seems to be mixed with legacy code that has been deprecated since around Python 3.4, so modcell has made some modifications. ____ is inside. If modcell doesn't work because of version, you should try @ tdual's code.
The linked code will execute all the code cells of the notebook loaded as a module, so try modifying it so that the cell with # modcell
in the comment at the beginning of the code cell is identified and loaded. It was.
Please use it if you like because it was released as a library called modcell
.
(If you look for it, there should be someone who makes a library that is clever than me, so if anyone knows a good library, I would appreciate it if you could let me know.)
Usage
modcell
searches for files with the extension .ipynb
that exist in the directory registered in sys.path
, and is written in the first line (excluding magic commands) of the code cell. Identify the comment # modcell
and import it as a module.
pip install modcell
Importing the modcell
module adds a loader to sys.meta_path
to load the .ipynb
. After that, it is possible to import files with the extension .ipynb
.
import modcell as mods
Importing with a name without the extension, just like a regular module, will import all cells with # modcell
at the beginning of the cell (except for the IPython magic command).
Notebook on the imported side(test_module.ipynb)A certain cell
# modcell
class TestModule:
def __init__(self):
pass
def hello(self):
print('Hello from TestModule')
A certain cell in the notebook on the importing side
import test_module as mod
x = mod.TestModule()
x.hello()
modcell
ignores IPython magic commands (lines starting with!
Or%
). That is, % autoreload
and %% time
are not executed when importing by modcell
.
Also, I don't know if modcell
itself supports% autoreload
because I haven't tested it. We have confirmed that if you do Restart and Run all
, other notebooks will be reloaded.
Upward compatible with %% writefile
. Outputs all imported cells to a file.
import modcell as mods
import test_module
with open('module.py', mode='w') as f:
mods.compile(out=f, source_info=True)
It is formatted as follows.
module.py
# test_module.ipynb ---------
# ---
class TestModule:
def __init__(self):
pass
def hello(self):
print('Hello from TestModule')
# ---
# --------- test_module.ipynb
The delimited comment corresponding to the cell is output from the viewpoint of debugging etc., but if it is in the way, it will not be output if source_info = False
is specified.
Write a comment at the beginning of the cell
test_module.A certain cell of ipynb
# modcell: tagname
class TestModule:
def __init__(self):
pass
def hello(self):
print('Hello from TestModule')
You can add only one tag to each cell by using the syntax of. When importing
import modcell as mods
mod = mods._import('test_module', tag='tagname')
x = mod.TestModule().hello()
By doing so, only cells with the tag tagname
can be read.
By default, modcell
creates one instance of the modcell.ModCell
class, and all functions are executed as methods of that default instance. This default instance can be obtained with the modcell.default ()
function, but it is deprecated by the user.
Users can create multiple ModCell
instances as needed.
import modcell as mods
mod_1 = mods.ModCell()
mod_2 = mods.ModCell()
...
In other words, you can generate multiple .py
files from multiple .ipynb
by executing the following code.
import modcell as mods
mod_debug = mods.ModCell()
nb1_debug = mod_debug._import('notebook_1', tag='debug')
nb2 = mod_debug._import('notebook_2')
nb3 = mod_debug._import('notebook_3')
with open('../module/mod_debug.py', mode='w') as f:
mod_debug.compile(out=f)
mod_test = mods.ModCell()
nb1_test = mod_test._import('notebook_1', tag='test')
nb4 = mod_test._import('notebook_4')
with open('../module/mod_test.py', mode='w') as f:
mod_test.compile(out=f)
Another way I came up with was to "attach to the IPython kernel and pull the contents of the code cells of other notebooks", but it seems that the contents of the code cells are retained by the front-end JavaScript. However, the IPython kernel seems to hold only the code after the parser is applied, so it was a bad idea.
https://stackoverflow.com/questions/51121647/get-the-current-contents-of-the-entire-jupyter-notebook
Recommended Posts