有没有办法防止在堆栈上到达程序顶层时多次捕获异常?
这是一个非常简化的代码示例,说明了这种现象:
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
我只想打印一次“错误”。
在我的软件中,try_except_block
函数被包装到一个对象中,我有想法设置该对象的一个属性,该属性可以将异常语句标记为“已访问”或未访问。我不喜欢这个想法,因为这种做法可能会带来副作用。还有其他的吗?
我的想法示例(类属性由全局变量 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
最佳答案
我不完全理解为什么你的代码会做它所做的事情,但是你可以做的可能适合的事情是将异常对象标记为已经看到的,而不是设置全局标志。就像这样:
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
完成的额外处理将只发生一次每个异常对象,这可能就是您想要的。
关于python - 如何防止多次捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38330393/