首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用IPython的魔力运行单元格执行代码时捕获异常和中断(在异常上)

使用IPython的魔力运行单元格执行代码时捕获异常和中断(在异常上)
EN

Stack Overflow用户
提问于 2020-09-02 06:12:33
回答 2查看 385关注 0票数 1

当使用IPython的magick命令运行木星单元中的一些python命令时,如何捕获错误?

代码语言:javascript
复制
In [1]: from IPython import get_ipython
        from IPython.core.magics.namespace import NamespaceMagics
        from IPython.utils.capture import capture_output


In [2]: _nms = NamespaceMagics()
        _Jupyter = get_ipython()
        _nms.shell = _Jupyter.kernel.shell
        cell_capture = capture_output(stdout=True, stderr=True, display=True)

In [3]: cell = "y = z**2"

In [4]: with cell_capture:
            _nms.shell.run_cell(cell)
        
        print("This gets printed")

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-9-5330dcdc6092> in <module>
----> 1 y = z**2

NameError: name 'z' is not defined

This gets printed

除了使用exec运行单元格之外,还有什么方法可以打断我遇到NameError (或者其他任何Exception )?

编辑

我已经尝试过使用try....catch (但它不能解决这个问题):

代码语言:javascript
复制
In [5]: try:
            with cell_capture:
                _nms.shell.run_cell(cell)
        except Exception:
            raise

        print("Something here")


NameError                                 Traceback (most recent call last)
<ipython-input-29-5330dcdc6092> in <module>
----> 1 y = z**2

NameError: name 'z' is not defined

Something here

编辑2

代码语言:javascript
复制
try:
    with cell_capture:
        print('Inside cell capture here')
        _nms.shell.run_cell(cell)
except NameError:
    print("I'm in NameError")
    raise NameError("something bad happened")

print("Something here")


NameError                                 Traceback (most recent call last)
<ipython-input-33-5330dcdc6092> in <module>
----> 1 y = z**2

NameError: name 'z' is not defined

Something here
EN

回答 2

Stack Overflow用户

发布于 2020-11-20 15:27:07

调用InteractiveShell.run_cell()的结果是ExecutionResult的一个实例。它有"raise_error“方法,”如果成功是假的,则重新定义错误,否则什么也不做“。您可以捕获异常,处理它,并重新定位它(如果需要的话)。

代码语言:javascript
复制
with cell_capture:
    result = get_ipython().run_cell(cell)
    result.raise_error()

https://ipython.readthedocs.io/en/stable/api/generated/IPython.core.interactiveshell.html#IPython.core.interactiveshell.ExecutionResult

票数 0
EN

Stack Overflow用户

发布于 2022-04-09 10:13:11

注意:get_ipython()get_ipython().kernel.shell是同一个对象,因此get_ipython().run_cell(cell)与更长的链相同:

代码语言:javascript
复制
from IPython.core.interactiveshell import InteractiveShell, ExecutionResult
ishell:InteractiveShell = get_ipython()
print(id(ishell), id(ishell.kernel.shell))

(从技术上讲,get_ipython将返回ipykernel.zmqshell.ZMQInteractiveShell (木星)或google.colab._shell.Shell (Colab),但它们都扩展了IPython.core.interactiveshell.InteractiveShell)

对我来说,这并没有通过shell.run_cell

代码语言:javascript
复制
from IPython.core.interactiveshell import InteractiveShell, ExecutionResult
from IPython.utils.capture import capture_output, CapturedIO
cell = 'print("hello world")\nraise ValueError("hello sun")'
shell:InteractiveShell = get_ipython()  # noqa `get_ipython` is present in notebooks
with capture_output(stdout=True, stderr=True, display=True) as captured: #: CapturedIO
    try:
        print('hello mercury')
        result:ExecutionResult = shell.run_cell(cell)
        print(captured.stdout)
        print(captured.stderr)
        print(captured.outputs)
    except Exception as error:
        print('hello world')
        print(type(error))

因为capture_output没有停止错误,所以它只会屏蔽它们:

代码语言:javascript
复制
cell = 'print("hello world")\nraise ValueError("hello sun")'
shell:InteractiveShell = get_ipython()  # noqa `get_ipython` is present in notebooks
with capture_output(stdout=False, stderr=True, display=False) as captured: #: CapturedIO
    result:ExecutionResult = shell.run_cell(cell)
print('hello jupyter') # this is never run.

因此,问题在shell.run_cell中是有问题的。检查它做了什么:

代码语言:javascript
复制
import inspect
print(inspect.getsource(shell.run_cell)))

将mro升级到InteractiveShell().run_cell

代码语言:javascript
复制
print(inspect.getsource(InteractiveShell.run_cell))

给予:

代码语言:javascript
复制
    result = None
try:
    result = self._run_cell(
        raw_cell, store_history, silent, shell_futures)
finally:
    self.events.trigger('post_execute')
    if not silent:
        self.events.trigger('post_run_cell', result)
return result

触发器引起了我的注意..。至少对于我的应用程序(跟踪错误)来说,这可以很好地获得错误:

代码语言:javascript
复制
def foo(result: ExecutionResult):
    pass

shell.events.callbacks['post_run_cell'].append(foo)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63699652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档