Jupyter Notebook:发生崩溃时如何重新启动上面的所有单元格?
Jupyter Notebook: How to relaunch all cells above when a crash occurs?
问题 1:
我正在使用带有 python 的 jupyter 4,我需要我的脚本在发生崩溃时重新启动上面的所有单元格。
这可能吗?
问题 2:
如果我需要重新启动所有的一些cell,我可以让python根据一些cell-id执行它们吗?然后我可以创建一个单元格 ID 列表,在捕获异常时必须重新执行这些单元格 ID...
我是 运行 Notebook server 5.4.0,我有一个选项 Cell > Run All Above
,它似乎正是这样做的。
您始终可以使用 Cell > Run All Above
重新启动活动单元格上方的所有单元格。但是当谈到以编程方式可靠地这样做时,我有好消息也有坏消息要告诉你。
让我们把关于问题 2 的坏消息排除在外:否
...至少不是很可靠,因为如果您插入或删除任何其他单元格,单元格的任何 ID 都会改变。
根据 Execute specific cells through widgets and conditions 在 github 上的说法:
We don't have the Ids of of cell in order to handle them
programatically.
再往下 post:
There are some APIs which can run cells identified by numbers, but
unfortunately the numbers change if you insert or delete a cell
somewhere above.
关于第一个问题的好消息:是
...但不能 100% 确定它会根据您问题中的详细信息解决您的错误处理需求。但我们稍后会谈到这一点。因为好消息是标题中问题的答案
How to relaunch all cells above when a crash occurs?
是是的,我们可以!
这个问题的难点(甚至可能是不可能的)部分是将其实现为一种健壮的错误处理方法。如果您只对此感兴趣,请跳至我的回答末尾的 The hard part
部分。现在,让我们继续 easy part
,即以编程方式 运行 菜单选项 Cell > Run All
(如 Nic Cottrell 的回答中所述) .您有两个选择:
选项1 - 运行上面所有单元格执行一个单元格:
如果您在单元格中插入以下代码段 运行,上面的所有单元格都将被执行:
from IPython.display import Javascript
display(Javascript('IPython.notebook.execute_cells_above()'))
选项 2 - 运行 通过单击按钮上方的所有单元格:
如果您在单元格中插入以下代码片段 运行,当您单击出现的按钮时,上面的所有单元格都将被执行:
片段:
from IPython.core.display import display, HTML
HTML('''<script> </script> <form action="javascript:IPython.notebook.execute_cells_above()"><input type="submit" id="toggleButton" value="Run all"></form>''')
输出:
THE HARD PART
那么,我们如何设置它以在发生崩溃时处理错误?我不是这方面的专家,但我认为我已经能够进行适合您的设置。但这很可能取决于相关错误的类型和您的其余工作流程。
以下示例基于两个不同的错误消息。第一个是 NameError
,当您尝试为不存在的变量赋值时出现。这将很有用,因为 re-running 错误后的某些单元格需要一个迭代器,该迭代器仅在笔记本完全重新启动时才重置,而不是当单元格 re-run 作为错误处理方法的一部分时。只有在重新启动笔记本电脑时重新启动内核时才会出现名称错误。作为错误处理的一部分,值 0
被分配给 x1
。当单元格只有re-run时x1
会增加1
.
第二个错误将作为 您的 错误的代理,并且是每次尝试 delete an element from a list that does not exist。这给我们带来了真正的挑战,因为如果您的错误处理程序 re-run 每次触发错误时都包含上面的所有单元格,您很快就会陷入错误的循环。但是我们将使用一个计数器来处理这个问题,该计数器会在 运行 秒后退出单元格的循环执行。
似乎不存在重新运行您的现有单元格的功能也有点问题,或初始化 run cells above
功能的单元格。但我们将使用与之前相同的 github post 的另一个建议来处理该问题:
Doing the following helps me to execute the cell right below the code
cell. You can also change the values to get cells in other parts of
the notebook.
display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1, IPython.notebook.get_selected_index()+2)'))
建议的笔记本 work-flow:
在下面的四个单元格中插入以下四个片段。单击菜单选项 Cell > Run all
一次,我们就可以开始了!
片段 1 - 导入和设置
import sys
import os
from IPython.core.display import display, HTML
from IPython.display import Javascript
from random import randint
# Trigger to randomly raise en error in the next cell
ErrorTrigger = randint(0, 9)
# Assignment of variables at first run of the Norebook
try: x1
except NameError: x1 = None
if x1 is None:
%qtconsole # opens a qtconsole (for variable inspection and debugging)
x1 = 0 # counter for NameError
x2 = 0 # counter for assignment error (used in cells below)
mr = 0 # counter for manual relaunch by button
ErrorTriggers=[] # container for ErroTriggers
print('NameErrors = ', x1)
else:
x1 = x1 + 1
ErrorTriggers.append(ErrorTrigger)
#print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)
代码段 2 - 错误的代理
# PROXY ERROR => INSERT YOUR CODE FROM HERE ################################################################
list1 = [1,2,3,4]
# 80 % chance of raising an error trying to delete an element that does not exist in the list
if ErrorTrigger > 2:
elemDelete = 8 # error
else:
elemDelete = 0 # not error
try:
del list1[elemDelete]
print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)
print('Routine success on attempt', x2 + 1)
print('Error mesg: None')
ErrorTriggers=[]
x2 = 0 # reset error counter
# TO HERE #################################################################################################
except Exception:
x2 = x2 + 1
# Will end error handler after 5 attempts
if x2 < 3:
# As long as we're UNDER the attempt limit, the next cell executed by:
display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1,'+
' IPython.notebook.get_selected_index()+2)'))
else:
# If we're OVER the attempt limit, it all ends here. The next cell is NOT run.
# And NEITHER is the last cell with the button to relaunch the whole thing.
print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)
print('Routine aborted after attempt', x2)
print('Error msg:', sys.exc_info()[1]) # Returns a message describing the error
# reset variables
ErrorTriggers = []
x2 = 0
代码段 3 - 重新运行 上述所有单元格作为错误处理程序的单元格
display(Javascript('IPython.notebook.execute_cells_above()'))
片段 4 - 重新运行 整个事情的单元格,错误概率为 20%
HTML('''<script> </script> <form action="javascript:IPython.notebook.execute_cells_above()"><input type="submit" id="toggleButton" value="Run again!"></form>''')
几次测试后的截图运行s:
如果片段中的评论不清楚,我很乐意添加更多详细信息。
但是,如果您通过单击 Run Again!
多次 运行 笔记本,同时查看单元格 3 的输出,您将很快掌握整个内容是如何组合在一起的:
这是用于 jupyterlab
转到:Settings->Advanced Settings Editor->Keyboard Shortcuts
将下面的代码粘贴到 User Preferences
window:
{
"shortcuts": [
{
"command": "notebook:run-all-above",
"keys": [
"Shift Backspace"
],
"selector": ".jp-Notebook.jp-mod-editMode"
}
]
}
- 点击保存(
user-preferences
右上window)
这将立即生效。在这里,连续按两次 shift + backspace
会运行所选行上方的所有单元格。
值得注意的是,system defaults
具有所有菜单命令的空模板,包括此代码(搜索 run-all-above
)。
在 Jupyter 中,在出错后单击您想要 re-run 的每个单元格,然后转到“查看”>“单元格工具栏”>“标签”。在单元格顶部的框中键入 'raises-exception'(无引号)并添加标签。
在下一个单元格中,输入以下内容:
from IPython.display import Javascript
Javascript("IPython.notebook.execute_all_cells()")
然后 select 单元格 > 运行 全部。
这应该会捕获错误并且 运行 无限循环中的所有单元格,直到被中断。
问题 1:
我正在使用带有 python 的 jupyter 4,我需要我的脚本在发生崩溃时重新启动上面的所有单元格。
这可能吗?
问题 2:
如果我需要重新启动所有的一些cell,我可以让python根据一些cell-id执行它们吗?然后我可以创建一个单元格 ID 列表,在捕获异常时必须重新执行这些单元格 ID...
我是 运行 Notebook server 5.4.0,我有一个选项 Cell > Run All Above
,它似乎正是这样做的。
您始终可以使用 Cell > Run All Above
重新启动活动单元格上方的所有单元格。但是当谈到以编程方式可靠地这样做时,我有好消息也有坏消息要告诉你。
让我们把关于问题 2 的坏消息排除在外:否
...至少不是很可靠,因为如果您插入或删除任何其他单元格,单元格的任何 ID 都会改变。
根据 Execute specific cells through widgets and conditions 在 github 上的说法:
We don't have the Ids of of cell in order to handle them programatically.
再往下 post:
There are some APIs which can run cells identified by numbers, but unfortunately the numbers change if you insert or delete a cell somewhere above.
关于第一个问题的好消息:是
...但不能 100% 确定它会根据您问题中的详细信息解决您的错误处理需求。但我们稍后会谈到这一点。因为好消息是标题中问题的答案
How to relaunch all cells above when a crash occurs?
是是的,我们可以!
这个问题的难点(甚至可能是不可能的)部分是将其实现为一种健壮的错误处理方法。如果您只对此感兴趣,请跳至我的回答末尾的 The hard part
部分。现在,让我们继续 easy part
,即以编程方式 运行 菜单选项 Cell > Run All
(如 Nic Cottrell 的回答中所述) .您有两个选择:
选项1 - 运行上面所有单元格执行一个单元格:
如果您在单元格中插入以下代码段 运行,上面的所有单元格都将被执行:
from IPython.display import Javascript
display(Javascript('IPython.notebook.execute_cells_above()'))
选项 2 - 运行 通过单击按钮上方的所有单元格:
如果您在单元格中插入以下代码片段 运行,当您单击出现的按钮时,上面的所有单元格都将被执行:
片段:
from IPython.core.display import display, HTML
HTML('''<script> </script> <form action="javascript:IPython.notebook.execute_cells_above()"><input type="submit" id="toggleButton" value="Run all"></form>''')
输出:
THE HARD PART
那么,我们如何设置它以在发生崩溃时处理错误?我不是这方面的专家,但我认为我已经能够进行适合您的设置。但这很可能取决于相关错误的类型和您的其余工作流程。
以下示例基于两个不同的错误消息。第一个是 NameError
,当您尝试为不存在的变量赋值时出现。这将很有用,因为 re-running 错误后的某些单元格需要一个迭代器,该迭代器仅在笔记本完全重新启动时才重置,而不是当单元格 re-run 作为错误处理方法的一部分时。只有在重新启动笔记本电脑时重新启动内核时才会出现名称错误。作为错误处理的一部分,值 0
被分配给 x1
。当单元格只有re-run时x1
会增加1
.
第二个错误将作为 您的 错误的代理,并且是每次尝试 delete an element from a list that does not exist。这给我们带来了真正的挑战,因为如果您的错误处理程序 re-run 每次触发错误时都包含上面的所有单元格,您很快就会陷入错误的循环。但是我们将使用一个计数器来处理这个问题,该计数器会在 运行 秒后退出单元格的循环执行。
似乎不存在重新运行您的现有单元格的功能也有点问题,或初始化 run cells above
功能的单元格。但我们将使用与之前相同的 github post 的另一个建议来处理该问题:
Doing the following helps me to execute the cell right below the code cell. You can also change the values to get cells in other parts of the notebook.
display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1, IPython.notebook.get_selected_index()+2)'))
建议的笔记本 work-flow:
在下面的四个单元格中插入以下四个片段。单击菜单选项 Cell > Run all
一次,我们就可以开始了!
片段 1 - 导入和设置
import sys
import os
from IPython.core.display import display, HTML
from IPython.display import Javascript
from random import randint
# Trigger to randomly raise en error in the next cell
ErrorTrigger = randint(0, 9)
# Assignment of variables at first run of the Norebook
try: x1
except NameError: x1 = None
if x1 is None:
%qtconsole # opens a qtconsole (for variable inspection and debugging)
x1 = 0 # counter for NameError
x2 = 0 # counter for assignment error (used in cells below)
mr = 0 # counter for manual relaunch by button
ErrorTriggers=[] # container for ErroTriggers
print('NameErrors = ', x1)
else:
x1 = x1 + 1
ErrorTriggers.append(ErrorTrigger)
#print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)
代码段 2 - 错误的代理
# PROXY ERROR => INSERT YOUR CODE FROM HERE ################################################################
list1 = [1,2,3,4]
# 80 % chance of raising an error trying to delete an element that does not exist in the list
if ErrorTrigger > 2:
elemDelete = 8 # error
else:
elemDelete = 0 # not error
try:
del list1[elemDelete]
print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)
print('Routine success on attempt', x2 + 1)
print('Error mesg: None')
ErrorTriggers=[]
x2 = 0 # reset error counter
# TO HERE #################################################################################################
except Exception:
x2 = x2 + 1
# Will end error handler after 5 attempts
if x2 < 3:
# As long as we're UNDER the attempt limit, the next cell executed by:
display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1,'+
' IPython.notebook.get_selected_index()+2)'))
else:
# If we're OVER the attempt limit, it all ends here. The next cell is NOT run.
# And NEITHER is the last cell with the button to relaunch the whole thing.
print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)
print('Routine aborted after attempt', x2)
print('Error msg:', sys.exc_info()[1]) # Returns a message describing the error
# reset variables
ErrorTriggers = []
x2 = 0
代码段 3 - 重新运行 上述所有单元格作为错误处理程序的单元格
display(Javascript('IPython.notebook.execute_cells_above()'))
片段 4 - 重新运行 整个事情的单元格,错误概率为 20%
HTML('''<script> </script> <form action="javascript:IPython.notebook.execute_cells_above()"><input type="submit" id="toggleButton" value="Run again!"></form>''')
几次测试后的截图运行s:
如果片段中的评论不清楚,我很乐意添加更多详细信息。
但是,如果您通过单击 Run Again!
多次 运行 笔记本,同时查看单元格 3 的输出,您将很快掌握整个内容是如何组合在一起的:
这是用于 jupyterlab
转到:
Settings->Advanced Settings Editor->Keyboard Shortcuts
将下面的代码粘贴到
User Preferences
window:
{
"shortcuts": [
{
"command": "notebook:run-all-above",
"keys": [
"Shift Backspace"
],
"selector": ".jp-Notebook.jp-mod-editMode"
}
]
}
- 点击保存(
user-preferences
右上window)
这将立即生效。在这里,连续按两次 shift + backspace
会运行所选行上方的所有单元格。
值得注意的是,system defaults
具有所有菜单命令的空模板,包括此代码(搜索 run-all-above
)。
在 Jupyter 中,在出错后单击您想要 re-run 的每个单元格,然后转到“查看”>“单元格工具栏”>“标签”。在单元格顶部的框中键入 'raises-exception'(无引号)并添加标签。
在下一个单元格中,输入以下内容:
from IPython.display import Javascript
Javascript("IPython.notebook.execute_all_cells()")
然后 select 单元格 > 运行 全部。
这应该会捕获错误并且 运行 无限循环中的所有单元格,直到被中断。