gpt4 book ai didi

python - 在上下文管理器 __enter__() 中捕获异常

转载 作者:IT老高 更新时间:2023-10-28 20:40:18 24 4
gpt4 key购买 nike

是否可以保证 __exit__() 方法在 __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__
>>>

编辑

这是我能得到的最接近...

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

事后看来,上下文管理器可能不是最好的设计决策

最佳答案

像这样:

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

要让程序继续其愉快的方式而不执行上下文 block ,您需要检查上下文 block 内的上下文对象,并且只有在 __enter__ 成功时才执行重要的操作。

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"

据我所知,您不能完全跳过 with block 。请注意,此上下文现在将 all 异常包含在其中。如果您不希望在 __enter__ 成功时吞下异常,请检查 __exit__ 中的 self.enter_okreturn False 如果是是的

关于python - 在上下文管理器 __enter__() 中捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13074847/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com