有没有办法可以在上下文管理器的__enter__
方法中捕获异常而不将整个with
块包含在try
内?
class TstContx(object):
def __enter__(self):
raise Exception("I'd like to catch this exception")
def __exit__(self, e_typ, e_val, trcbak):
pass
with TstContx():
raise Exception("I don't want to catch this exception")
pass
我知道我可以在__enter__()
本身内捕获异常,但是我可以从包含with
语句的函数中访问该错误吗?
表面上问题Catching exception in context manager __enter__()
似乎是一回事,但问题实际上是确保__exit__
被调用,而不是将__enter__
代码与块不同with
语句包含。
......显然,动机应该更加清晰。 with
语句正在为完全自动化的进程设置一些日志记录。如果程序在设置日志记录之前失败,那么我就不能依赖日志记录来通知我,所以我必须做一些特殊的事情。而且我宁愿达到效果,而不必添加更多缩进,如下所示:
try:
with TstContx():
try:
print "Do something"
except Exception:
print "Here's where I would handle exception generated within the body of the with statement"
except Exception:
print "Here's where I'd handle an exception that occurs in __enter__ (and I suppose also __exit__)"
使用两个try
块的另一个缺点是,处理__enter__
中的异常的代码位于处理with
块的后续主体中的异常的代码之后。
答案 0 :(得分:2)
您可以使用try
内的except
/ __enter__
来捕获异常,然后将异常实例保存为TstContx
类的实例变量,以便您访问它位于with
块内:
class TstContx(object):
def __enter__(self):
self.exc = None
try:
raise Exception("I'd like to catch this exception")
except Exception as e:
self.exc = e
return self
def __exit__(self, e_typ, e_val, trcbak):
pass
with TstContx() as tst:
if tst.exc:
print("We caught an exception: '%s'" % tst.exc)
raise Exception("I don't want to catch this exception")
输出:
We caught an exception: 'I'd like to catch this exception'.
Traceback (most recent call last):
File "./torn.py", line 20, in <module>
raise Exception("I don't want to catch this exception")
Exception: I don't want to catch this exception
不确定为什么你想要这样做,不过......
答案 1 :(得分:0)
您可以使用contextlib.ExitStack
中概述的this doc example来分别检查<child-component>
错误:
__enter__