VSCode Jupyter环境下如何编程实现Run Cell Below功能
在VS Code Jupyter中编程实现「运行下方单元格」功能
问题背景
传统Jupyter环境下,可通过ipywidgets绑定按钮点击事件,注入前端JS调用IPython.notebook.execute_cells_below()实现点击按钮运行下方单元格的效果,原有实现代码如下:
import ipywidgets as widgets from IPython.display import display,Markdown,Javascript,HTML def run_below(ev): Javascript('IPython.notebook.execute_cells_below()') button = widgets.Button(description="Click to run cells below") button.on_click(run_below) display(button)
上述代码迁移到VS Code环境后点击按钮无响应,根因为VS Code Jupyter扩展采用独立前端实现,未暴露传统Jupyter前端的IPython.notebook全局对象,注入的JS脚本无法找到执行入口。
运行环境信息:
- Python版本:3.9.12
- VSCode版本:1.69.0
- VSCode Jupyter扩展版本:v2022.6.1001902341
可行实现方案
方案1:通过内核comm消息触发VS Code原生指令(推荐)
该方案适配VS Code Jupyter扩展的内置通信协议,和IDE原生「运行下方单元格」行为完全一致,代码如下:
import ipywidgets as widgets from IPython.display import display from IPython import get_ipython def run_below(ev): kernel = get_ipython().kernel # 向前端发送运行下方单元格的控制指令 comm = kernel.comm.Comm(target_name="vscode.jupyter.command") comm.send({"command": "notebook.cell.executeBelow"}) comm.close() button = widgets.Button(description="点击运行下方单元格") button.on_click(run_below) display(button)
方案2:纯内核侧实现(无前端依赖,兼容性最强)
该方案不依赖任何前端API,直接通过IPython内核接口执行后续单元格代码,无需适配不同版本的VS Code Jupyter扩展,代码如下:
import ipywidgets as widgets from IPython.display import display from IPython import get_ipython def run_below(ev): ipy = get_ipython() # 获取当前单元格执行位置,遍历执行后续所有单元格 cell_history = ipy.user_ns["_ih"] current_pos = len(cell_history) - 1 for cell_code in cell_history[current_pos + 1 :]: if cell_code.strip(): ipy.run_cell(cell_code) button = widgets.Button(description="点击运行下方单元格") button.on_click(run_below) display(button)
注意事项
- 方案1的指令适配v2022.4及以上版本的VS Code Jupyter扩展,和当前使用的v2022.6版本完全兼容
- 方案2执行时会读取内核存储的单元格历史,若下方单元格修改后未执行过,会运行上一次保存的代码版本,建议notebook全量保存后使用
- 不要继续使用
IPython.display.Javascript注入前端脚本的方案,VS Code Jupyter前端默认沙箱隔离了用户注入的JS对编辑器核心API的访问权限,这类写法在VS Code环境下不会生效。
内容的提问来源于stack exchange,提问作者Brian Keith
相关产品推荐
相关产品推荐

