如何防止多次捕获异常

2024-09-30 01:33:41 发布

您现在位置:Python中文网/ 问答频道 /正文

当异常沿着堆栈上升到程序的顶层时,是否有方法防止多次捕获异常

下面是一个非常简化的代码示例,说明了这种现象:

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函数被包装到一个对象中,我想设置这个对象的一个属性,该属性可以将异常语句标记为“已访问”或“未访问”。我不喜欢这个想法,因为这种做法可能会带来副作用。还有别的吗

我想到的示例(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

Tags: runinpydeflineexceptionargscall
1条回答
网友
1楼 · 发布于 2024-09-30 01:33:41

我不完全理解为什么您的代码会这样做,但是您可以做一件可能适合的事情,就是将异常对象标记为已经看到的对象,而不是设置全局标志。像这样:

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所做的额外处理只会对每个异常对象执行一次,这可能是您想要的

相关问题 更多 >

    热门问题