在上下文管理器中捕获异常__enter __() [英] Catching exception in context manager __enter__()
问题描述
有可能确保 __ exit __()
方法即使在 __中有异常__输入__()
?
>>> class TstContx(object):
... def __enter __(self):
... raise Exception('Oops in __enter__')
...
... def __exit __(self,e_typ,e_val,trcbak):
... print这不运行
...
>>>使用TstContx():
... pass
...
追溯(最近的最后一次调用):
文件< stdin>,第1行,模块>
文件< stdin>,第3行,__enter__
例外:在__enter__
>>>
修改
这是尽可能接近...
class TstContx(object):
def __enter __自我):
尝试:
#__enter__代码
除了例外作为e
self.init_exc = e
返回自我
def __exit __(self,e_typ,e_val,trcbak):
如果全部((e_typ,e_val,trcbak)):
raise e_typ,e_val,trcbak
#__exit__代码
with TstContx()as tc:
if hasattr(tc,'init_exc'):raise tc.init_exc
# b $ b
在后视中,上下文管理器可能尚未成为最佳设计决策
像这样:
import sys
类上下文(对象):
def __enter __(self):
try:
raise异常(哎呀在__ente
除了:
#如果__exit__返回一个真值,则运行异常
如果self .__ exit __(* sys.exc_info()):
pass
else:
raise
def __exit __(self,e_typ,e_val,trcbak):
print现在运行
with Context():
pass
让程序继续快乐的方式没有执行上下文块,您需要检查上下文块中的上下文对象,并且只有在 __输入__
成功时才能执行重要的操作。
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
$ b $ _ $($) :
try:
raise异常(哎呀在__enter__)
除了:
如果self .__退出__(* sys.exc_info()):
self.enter_ok = False
else:
def __exit __(self,e_typ,e_val,trcbak):
print现在运行两次
return True
与Context()作为c:
如果c.enter_ok:
打印仅在输入成功时运行
print执行继续
据我所知,您无法完全跳过with-block。并注意到这个上下文现在吞下了所有的例外。如果您不想吞下异常,如果 __输入__
成功,请在 __ exit __ 中检查
self.enter_ok
/ code>和 return False
如果它是 True
。
Is it possible to ensure the __exit__()
method is called even if there is an exception in __enter__()
?
>>> class TstContx(object):
... def __enter__(self):
... raise Exception('Oops in __enter__')
...
... def __exit__(self, e_typ, e_val, trcbak):
... print "This isn't running"
...
>>> with TstContx():
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __enter__
Exception: Oops in __enter__
>>>
Edit
This is as close as I could get...
class TstContx(object):
def __enter__(self):
try:
# __enter__ code
except Exception as e
self.init_exc = e
return self
def __exit__(self, e_typ, e_val, trcbak):
if all((e_typ, e_val, trcbak)):
raise e_typ, e_val, trcbak
# __exit__ code
with TstContx() as tc:
if hasattr(tc, 'init_exc'): raise tc.init_exc
# code in context
In hind sight, a context manager might have not been the best design decision
Like this:
import sys
class Context(object):
def __enter__(self):
try:
raise Exception("Oops in __enter__")
except:
# Swallow exception if __exit__ returns a True value
if self.__exit__(*sys.exc_info()):
pass
else:
raise
def __exit__(self, e_typ, e_val, trcbak):
print "Now it's running"
with Context():
pass
To let the program continue on its merry way without executing the context block you need to inspect the context object inside the context block and only do the important stuff if __enter__
succeeded.
class Context(object):
def __init__(self):
self.enter_ok = True
def __enter__(self):
try:
raise Exception("Oops in __enter__")
except:
if self.__exit__(*sys.exc_info()):
self.enter_ok = False
else:
raise
return self
def __exit__(self, e_typ, e_val, trcbak):
print "Now this runs twice"
return True
with Context() as c:
if c.enter_ok:
print "Only runs if enter succeeded"
print "Execution continues"
As far as I can determine, you can't skip the with-block entirely. And note that this context now swallows all exceptions in it. If you wish not to swallow exceptions if __enter__
succeeds, check self.enter_ok
in __exit__
and return False
if it's True
.
这篇关于在上下文管理器中捕获异常__enter __()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!