IPython Notebook - 单元格提前退出

101 投票
5 回答
67781 浏览
提问于 2025-04-18 08:21

我想在IPython Notebook中以编程的方式提前结束一个单元格。不过,使用 exit(0) 会导致内核崩溃。

那么,正确的做法是什么呢?我更希望不需要拆分单元格或者手动停止执行。

5 个回答

0

这远不是“正确”的做法,但有一种方法可以提前退出程序,那就是制造一个运行时错误。所以,与其用 exit(0) 这种干净的方式提前退出脚本,不如用一些不太干净的方式,比如:

print(variable_to_query)
() + 1

这样做会执行到这段代码为止(完成打印语句),然后就会出错。

4

我不是说这是个好主意,但你可以把单元格的开始部分放在一个单次循环里,然后用'break'来停止后面的执行。


for _ in range(1):
    # do some stuff
    if some_condition:
        break 

64

要安静地停止当前和后续的单元格:

class StopExecution(Exception):
    def _render_traceback_(self):
        return []

raise StopExecution
64

稍微更“正规”的选择:

这样做可以让你摆脱大部分的 try/except 块,除了最糟糕的情况。

raise KeyboardInterrupt

这是你代码的一个更简洁的版本:

assert(False)

或者简单点:

raise

如果你想省点打字的时间。

27

我把我之前在这里的回答重新发一遍,因为这个解决方案也适用于你的问题。它会...

  • 在退出时不会杀掉内核
  • 不会显示完整的错误追踪(在IPython终端中没有错误追踪)
  • 不需要你在代码中到处加上try/except来处理错误
  • 无论有没有IPython,都能正常工作,代码不需要改动

只需从下面的代码中导入'exit'到你的jupyter笔记本(IPython笔记本)中,然后调用'exit()'就可以了。它会退出,并让你知道...

 An exception has occurred, use %tb to see the full traceback.

 IpyExit 

"""
# ipython_exit.py
Allows exit() to work if script is invoked with IPython without
raising NameError Exception. Keeps kernel alive.

Use: import variable 'exit' in target script with
     'from ipython_exit import exit'    
"""

import sys
from io import StringIO
from IPython import get_ipython


class IpyExit(SystemExit):
    """Exit Exception for IPython.

    Exception temporarily redirects stderr to buffer.
    """
    def __init__(self):
        # print("exiting")  # optionally print some message to stdout, too
        # ... or do other stuff before exit
        sys.stderr = StringIO()

    def __del__(self):
        sys.stderr.close()
        sys.stderr = sys.__stderr__  # restore from backup


def ipy_exit():
    raise IpyExit


if get_ipython():    # ...run with IPython
    exit = ipy_exit  # rebind to custom exit
else:
    exit = exit      # just make exit importable

撰写回答