JupyterNotebook / JupyterLab:如何在出现错误时自动重新运行单元格?

问题描述 投票:0回答:1

我有一段代码需要处理大量数据,并且需要相当长的时间(大约 4 小时 - 我想过夜运行它)。库(selenium)中使用的一种方法在被上诉时会在大约 10% 的情况下返回错误,并且需要重新运行代码/单元格(与 Web scraped 的网站不一致)。

我找到了一种重新启动块的方法,而不会丢失处理数据的进度,但是,我必须手动检查错误并在发生错误时重新运行单元。我的问题是,这可以在不丢失局部变量的情况下自动完成吗?

代码的简化版本:

代码单元格 1:

#code
n = 0

代码单元 2 - 可能会返回错误:

for i in list[n:]:
    n += 1
    #code
    method_that can return an error
    #code

有没有办法重新启动第二个代码单元而不丢失存储的变量?

python jupyter-notebook jupyter-lab
1个回答
0
投票

只要内核未重新启动,在单元生命周期内创建的任何变量都会保留在那里,即使该行在中途出错。这意味着您可以从技术上注册一个 IPython 异常处理程序来修复错误并继续重新运行单元直到它正常工作。

至于实际重新运行单元:虽然“_X”变量在单元完成运行之前不会更新,但所有输入都会添加到全局列表中 -

In[]
- 无论它们是否真正完成。

将这两者结合起来意味着您可以“从技术上”做到这一点,但这并不是万无一失的。如果您希望它在末尾打印最初应该打印的内容,则必须以某种方式从 exec 调用外部打印结果,这是相当困难的。我能想到的就是将单元格文本放入函数中,插入返回值,将该函数调用分配给全局,然后在

exec
调用之外打印全局。但是,由于 Python 在其块中使用缩进而不是符号,因此您必须重新格式化单元格以遵循规范,并且查找要输出的表达式的开始或结束位置并非易事。
这是我的 SymPy 计算器会话中的一个示例,它将任何未定义的变量用法转换为符号:

from IPython.core.ultratb import AutoFormattedTB # initialize the formatter for making the tracebacks into strings itb = AutoFormattedTB(mode = 'Plain', tb_offset = 1) findNameFromNameError = r"'([^']*)'" from IPython.display import display def undefNamesBecomeSymbols(self, etype, evalue, tb, tb_offset=None): if isinstance(evalue.name, str) and evalue.name.isalpha(): # makes sure it's a real name to be defined and not a reference like "_4" # Turn the cell's input into a code block that can be executed at once split = In[-1].split('\n') cellBlockCall = "def _undef_out():\n\t" + ("\n\t".join(split)) + "\nundef_placeholder = _undef_out()" symbolToCreate = evalue.name # avoid getting stuck in an infinite loop for i in range(0, 100): try: # create the undefined variable as a symbol with that name exec(f'{symbolToCreate} = Symbol("{symbolToCreate}")', globals()) exec(cellBlockCall, globals()) # "rerun" the cell display(undef_placeholder) # print the cell's output return None # don't return a traceback except NameError as err: # if the exec call throws another exception, just keep iterating var_name = re.findall(findNameFromNameError, str(err))[0] symbolToCreate = var_name # if we don't run or we go too long, return the structured traceback the error handler expects stb = itb.structured_traceback(etype, evalue, tb) return itb.stb2text(stb) # register the custom error handler with IPython get_ipython().set_custom_exc((NameError,), undefNamesBecomeSymbols)

© www.soinside.com 2019 - 2024. All rights reserved.