无论Excpetion类型如何,我都希望在发生异常时打印一条消息。
我尝试了以下内容:
class MyException(BaseException):
def __init__(self, msg):
super(BaseException, self).__init__(msg)
print "Howdy", msg
__builtins__.Exception = MyException
try:
raise IOError("world")
except Exception as e:
pass
我期待打印“Howdy world”,但我什么都没得到。
编辑:
@helmut建议使用sys.settrace,以下代码按预期工作。
import sys
def trace(frame, event, arg):
print event
return trace
sys.settrace(trace)
def foo():
raise Exception()
def bar():
foo()
def baz():
try:
bar()
except:
pass
baz()
exit()
太糟糕了,这对我的用例来说太慢了。
答案 0 :(得分:6)
为什么不进行猴子补丁?
让我解释为什么预计的方法存在缺陷。将MyException
分配给Exception
时会发生的情况是您更改了此模块中的全局变量Exception
。在此分配之前或在不同模块中定义的所有异常类都不会使用它。他们将使用原始值。由于IOError
是在解释器启动期间创建的,因此您的分配对其没有影响。因此,如果您要修补Exception
类,那么您将覆盖其方法。最重要的是,您将更改其__init__
和__new__
方法。不幸的是,不支持该方法,并且更改这些属性会导致:
TypeError: can't set attributes of built-in/extension type 'exceptions.Exception'
因此修补解释器的方法可能无法解决。
替代方案:追踪
另一种方法是编写一个要传递给sys.settrace
的函数。它为每个函数调用调用,如果要跟踪特定调用,则应返回另一个跟踪函数。各种事件被传递给后一个跟踪函数,其中一个是'exception'
。通过过滤这些事件,您可能已经达到了预期的效果。