在上下文管理器中捕获异常

编程入门 行业动态 更新时间:2024-10-23 13:22:19
本文介绍了在上下文管理器中捕获异常__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.

更多推荐

在上下文管理器中捕获异常

本文发布于:2023-11-23 10:07:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1621052.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:下文   在上   器中   异常

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!