gpt4 book ai didi

python - 如何操作上下文管理器的 __exit__ 中的异常?

转载 作者:太空狗 更新时间:2023-10-29 21:43:03 26 4
gpt4 key购买 nike

我知道从上下文管理器的 __exit__() 方法中重新引发异常是不好的风格。因此,我想在实例上附加一个属性,该属性可以携带上下文信息,如果我让异常通过或捕获它,则该信息不可用。这将避免重新提高它。

在异常上附加属性的替代方法是吞下异常,在兼作相关上下文管理器的实例上设置一些状态,然后检查该状态。问题是这会导致陷阱 22,不是吗?因为异常意味着正在退出 with block 内的执行。除了再次进入with block 之外,没有办法重复操作,对吧?因此,一旦 __exit__() 方法返回,我尝试存储上下文信息的实例就会消失。

简而言之:在 __exit__() 方法中,我如何操作挂起的实际异常(如果是,我将假定为这个问题给出的异常)?

最佳答案

上下文管理器不会因为 block 退出而消失。您可以通过两种方式保存它:

  1. 首先创建上下文管理器,将其分配给一个变量,然后对该对象使用 with:

    cm = ContextManager()
    with cm:
    # ....

    state = cm.attribute
  2. __enter__ 方法返回上下文管理器本身,使用 with ... as ... 将其绑定(bind)到本地名称。当 with 退出时,该名称未解除绑定(bind):

    with ContextManager() as cm:
    # ....

    state = cm.attribute

    其中 ContextManager.__enter__ 使用 return self

您还可以在异常本身上设置额外的属性;无需重新引发异常:

>>> class ContextManager(object):
... def __enter__(self):
... return self
... def __exit__(self, tp, v, tb):
... if tp is None: return
... v.extra_attribute = 'foobar'
... self.other_extra_attribute = 'spam-n-ham'
...
>>> try:
... with ContextManager() as cm:
... raise ValueError('barfoo')
... except ValueError as ex:
... print vars(ex)
...
{'extra_attribute': 'foobar'}
>>> vars(cm)
{'other_extra_attribute': 'spam-n-ham'}

这里为异常赋予了一个额外的属性,该属性一直存在到异常处理程序中。在上面,我还表明 cm 仍然绑定(bind)到上下文管理器。

关于python - 如何操作上下文管理器的 __exit__ 中的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26907175/

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