有可能确保 __ 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 contextIn 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(): passTo 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.
更多推荐
在上下文管理器中捕获异常
发布评论