避免在包开发模式下重新启动 Jupyter 内核?

Posted

技术标签:

【中文标题】避免在包开发模式下重新启动 Jupyter 内核?【英文标题】:Avoid restarting Jupyter kernel in package develop mode? 【发布时间】:2018-06-02 19:02:03 【问题描述】:

作为开发人员,我正在开发一个 python 包。该包存储在一个 git repo 中,我使用本地分支来调试/修复这个包。

我使用 Jupyter notebooks 在编辑模式下使用 pip 将我的本地分支作为一个包加载,我在其中测试我所做的更改。

我执行以下步骤:

    在开发模式下加载本地包 导入我要测试的模块 进行测试

例如:

! pip install -e Path/To/Local/Package/ # step 1

import local_foo as foo # step 2
foo.print() # step 3

在第 3 步之后,如果代码的行为不符合预期,我会更正我的包,重新启动 jupyter 内核,然后重新运行前面的 3 个步骤,直到获得我想要的行为。

我的问题是: 有没有办法避免重启内核?

我尝试了以下方法,但在这种情况下不起作用:IPython 自动重载

%load_ext autoreload
%autoreload 2

importlib.reload

import importlib
importlib.reload(foo)

我尝试了本文建议的解决方案:https://support.enthought.com/hc/en-us/articles/204469240-Jupyter-IPython-After-editing-a-module-changes-are-not-effective-without-kernel-restart

非常感谢!


PS:另外,你们中的一些人能否分享使用 Jupyter 笔记本管理 python 包开发(测试、...)的技巧、工作流程或经验?

【问题讨论】:

您能否发布一个您尝试使用autoreload 扩展的代码示例?为什么它不起作用?你有什么努力让它发挥作用? 【参考方案1】:

我在 jupyter notebook 中导入自定义脚本时遇到了类似的问题

尝试将模块作为别名导入,然后重新加载它

import local_foo as foo
from importlib import reload
reload(foo)

【讨论】:

【参考方案2】:

您可以使用autoreload,将这两行添加到您的 Jupyter notebook 的开头:

%reload_ext autoreload
%autoreload 2

【讨论】:

【参考方案3】:

您可能需要处理参考问题,因为使用 importlib.reload 可能无法轻松地重新加载非纯 Python 包。

这可以通过在重新加载之前从模块和命名空间中删除来解决。

import foo  # The first import of the package

import sys
import importlib

# Do things with foo

del sys.modules['foo']  # Remove it from the currently loaded modules
del foo  # Remove it's name

importlib.reload(foo)

Joseph Garvin 在this answer 中编写了一个非常好的函数,它的操作类似并且还支持from foo import bar 形式的导入。

【讨论】:

以上是关于避免在包开发模式下重新启动 Jupyter 内核?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免输出到 jupyter notebook 中的可滚动框架?

当本地模块中的代码发生更改时,我是不是总是必须在 Jupyter Lab 中重新启动内核?

Jupyter Notebook 中的内核死机和重启问题

如何调试垂死的 Jupyter Python3 内核?

Jupyter笔记本 - Dead Kernel

内核在jupyter笔记本中不断死亡