有没有办法防止在将堆栈升级到程序的最高级别时多次捕获异常?
这是一个非常简化的代码示例,用于说明这种现象:
def try_except_block(smthg):
try:
smthg.run()
except Exception as e:
print("WRONG")
raise e
def re_call():
f2 = Foo(True) # will throw an exception
try_except_block(f2)
class Foo:
def __init__(self, t):
self.throw = t
def run(self):
if self.throw:
raise KeyError
else:
re_call()
if __name__ == '__main__':
f = Foo(False) # won't throw an exception
try_except_block(f)
输出:
WRONG
WRONG
Traceback (most recent call last):
File "exception_loosing_args.py", line 26, in <module>
try_except_block(f)
File "exception_loosing_args.py", line 9, in try_except_block
raise e
File "exception_loosing_args.py", line 6, in try_except_block
smthg.run()
File "exception_loosing_args.py", line 22, in run
re_call()
File "exception_loosing_args.py", line 13, in re_call
try_except_block(f2)
File "exception_loosing_args.py", line 9, in try_except_block
raise e
File "exception_loosing_args.py", line 6, in try_except_block
smthg.run()
File "exception_loosing_args.py", line 20, in run
raise KeyError
KeyError
我只打印一次&#34;错误&#34;。
在我的软件中,try_except_block
函数被包装到一个对象中,我有想法设置这个对象的属性,该属性可以将异常语句标记为&#34;已经访问过&#34;或不。我不喜欢这个想法,因为这可能导致这种可能的副作用。还有另外一个吗?
示例我想到的(class属性由全局变量flag
模拟):
flag = False
def try_except_block(smthg):
global flag
try:
smthg.run()
except Exception as e:
if not flag:
print("WRONG")
flag = True
raise e
def re_call():
f2 = Foo(True) # will throw an exception
try_except_block(f2)
class Foo:
def __init__(self, t):
self.throw = t
def run(self):
if self.throw:
raise KeyError
else:
re_call()
if __name__ == '__main__':
f = Foo(False) # won't throw an exception
try_except_block(f)
输出:
WRONG
Traceback (most recent call last):
File "exception_loosing_args.py", line 28, in <module>
try_except_block(f)
File "exception_loosing_args.py", line 11, in try_except_block
raise e
File "exception_loosing_args.py", line 6, in try_except_block
smthg.run()
File "exception_loosing_args.py", line 24, in run
re_call()
File "exception_loosing_args.py", line 15, in re_call
try_except_block(f2)
File "exception_loosing_args.py", line 11, in try_except_block
raise e
File "exception_loosing_args.py", line 6, in try_except_block
smthg.run()
File "exception_loosing_args.py", line 22, in run
raise KeyError
KeyError
答案 0 :(得分:2)
我不完全理解为什么你的代码会做它的功能,但是可能适合的事情是将异常对象标记为已经看到,而不是设置全局标志。像这样:
def try_except_block(smthg):
try:
smthg.run()
except Exception as e:
if not hasattr(e, "teb_already_seen"):
setattr(e, "teb_already_seen", True)
print("WRONG")
raise e
这样,try_except_block
完成的额外处理只会发生一次每个异常对象,这可能是你想要的。