How can I suppress a given exception in a Context Manager?
本问题已经有最佳答案,请猛点这里访问。
当尝试忽略在执行上下文管理器期间引发的异常时,我的选项是什么?同样,以下简单的上下文管理器只传播结果,导致它结束执行,除非捕获:
1 2 3 4 5 6 7 8 9 10 | class contextMan: def __enter__(self): print("Entering Context") def __exit__(self, exc_type, exc_value, traceback): print("Exiting Context") if __name__ =="__main__": with contextMan(): raise IndexError |
我当然可以用一个
除了将其包装在
如果给定的异常应该被抑制,则使用返回
这将适用于
使用具有给定异常名称的
这只适用于版本
第一个选项是一个值得注意的选项,因为它可以在大多数的Python上使用,所以可以移植。它可以通过使用所需的异常来初始化上下文管理器,并在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class contextMan: def __init__(self, exception): self.exception = exception def __enter__(self): print("Entering Context") def __exit__(self, exc_type, exc_value, traceback): print("Exiting Context") return isinstance(exc_value, self.exception) if __name__ =="__main__": with contextMan(IndexError): raise IndexError |
这将抑制任何
1 2 | Entering Context Exiting Context |
这种方法的缺点是,您要为每个实例添加一个额外的属性,并在一个对象中组合两个不同的逻辑任务,而不是将它们分离。
第二个选项更加健壮、明确和通用。它是专门为这些场景创建的。它也是一个上下文管理器,因此,通常可以在应该抑制特定异常的任何情况下使用。
呼叫签名的形式如下:
1 | contextlib.suppress(*exceptions) |
其中
1 2 3 4 5 6 7 8 9 10 11 | class contextMan: def __enter__(self): print("Entering Context") def __exit__(self, exc_type, exc_value, traceback): print("Exiting Context") if __name__ =="__main__": with contextlib.suppress("IndexError") with contextMan(): raise IndexError |
也可以写在同一行,但这会导致一个相当冗长的声明。明显的缺点是,每次使用上下文管理器时,它都会引入另一个语句。
尽管有两种选择,但应该有一种——最好只有一种——显而易见的方法,我相信第二种是显而易见的方法(至少对于最近的版本)。