0xC*_*22L 7 python python-2.x contextmanager
我知道从上下文管理器的__exit__()方法中重新引发异常是不好的方式.所以,我想在实例上添加一个属性,该属性可以携带不可用的上下文信息,如果我让异常通过或如果我抓住它.这样可以避免重新提升它.
在异常上添加属性的替代方法是吞下异常,在实例上设置一些状态,该状态兼作相关的上下文管理器,然后检查该状态.问题是,这会导致捕获22,不是吗?由于异常意味着with正在退出块内执行.除了with再次进入阻止之外,没有办法重复操作,对吧?因此,一旦__exit__()方法返回,我试图存储上下文信息的实例就会消失.
简而言之:在方法中,如何操作待处理的实际异常(如果是,我将假设为此问题的假设)__exit__()?
上下文管理器不会因为块退出而消失.您可以通过两种方式保留它:
首先创建上下文管理器,将其分配给变量,然后使用with该对象:
cm = ContextManager()
with cm:
# ....
state = cm.attribute
Run Code Online (Sandbox Code Playgroud)从__enter__方法返回上下文管理器本身,用于with ... as ...将其绑定到本地名称.with退出时该名称不受限制:
with ContextManager as cm:
# ....
state = cm.attribute
Run Code Online (Sandbox Code Playgroud)
在哪里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'}
Run Code Online (Sandbox Code Playgroud)
在这里,异常被赋予了一个额外的属性,该属性一直持久到异常处理程序.在上面我也表明cm仍然绑定到上下文管理器.