python - 如何防止多次捕获异常

标签 python oop exception

有没有办法防止在堆栈上到达程序顶层时多次捕获异常?

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

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/

相关文章:

java - 方法调用者和被调用者,循环类级别方法调用

java - 可以在 ArrayList 上设置和调用,抛出 UnsupportedException

python - 如何查找缺少类型注释的代码?

python - 使用 Django 将文件发送到 GCS 的最佳方式

python - 将 python.exe 重命名为 python3.exe 以便与 Windows 上的 python2 共存

java - 如何在 Spring 中实现 GraphQL 的异常处理程序

c# - 返回 null 以避免 C# 中的方法出现未知异常

python - 列表理解 : why is this a syntax error?

python - 为什么这个类变量在不同的实例中是相同的?

c++ - 如何为 C++ 中的每个类初始化返回相同的实例?