Python 在settrace'中处理异常;返回';电话

Python 在settrace'中处理异常;返回';电话,python,python-3.x,Python,Python 3.x,在Python2.x中,传递给处理程序的frame对象具有f_exc_type属性 在Python3.x中,这个f_exc_类型已被删除 如果函数正在传播异常,则会调用跟踪“return”,但参数为None,sys.exc_info()为(None,None,None)。以下章节对此进行了描述: [return]函数(或其他代码块)即将返回。本地跟踪 函数被调用;arg是将返回的值,如果 该事件是由引发的异常引起的。跟踪函数的 返回值被忽略 在Python3中,跟踪程序如何在returnhook

在Python2.x中,传递给处理程序的frame对象具有
f_exc_type
属性

在Python3.x中,这个
f_exc_类型
已被删除

如果函数正在传播异常,则会调用跟踪“return”,但参数为
None
sys.exc_info()
(None,None,None)
。以下章节对此进行了描述:

[return]
函数(或其他代码块)即将返回。本地跟踪 函数被调用;arg是将返回的值,如果 该事件是由引发的异常引起的。跟踪函数的 返回值被忽略


在Python3中,跟踪程序如何在
return
hook中确定异常正在传播?它如何将它与正常返回
None
的函数区分开来呢?

这看起来确实很糟糕。这有点像黑客,但你可以通过查看最后一条指令的字节码来分辨区别:

import opcode

def tracer(frame, event, arg):
    if event == 'return':
        if arg is not None or (opcode.opname[frame.f_code.co_code[frame.f_lasti]]
                               in ('RETURN_VALUE', 'YIELD_VALUE')):
            print('exit via return', arg)
        else:
            print('exit via exception')

让我发抖,但它确实有效!非常感谢。这很好,但我发现它不起作用-如果在
try
块中使用
finally
子句返回None,那么它将在完成finally块后退出,操作码将是END\u finally,因此此代码将报告异常。但我没有看到完美的解决方案,因为如果在
try
中引发异常,操作码也会发生。