我有一个对象的上下文管理器,可以使用类似于open上下文管理器。
with MyContextManager as cm:
cm.do_something()我知道,如果使用contextlib.ContextDecorator创建一个简单的上下文管理器,它就可以变成一个装饰器。如果使用装饰器,也可以访问上下文管理器生成的对象吗?例如,考虑到上面的上下文管理器,如下所示:
@cmdecorator
def my_function(self, cm):
cm.do_something我不能让它起作用。要么我错过了一些微不足道的东西(希望如此),要么这是不可能的.最后它只是语法糖,但如果可能的话,我很感兴趣。
发布于 2020-02-25 19:45:54
要回答我自己的问题:虽然没有自动机制,但是编写一个精确的装饰器(使用硬编码的关键字参数)是非常容易的:
def patch_cm(f):
@functools.wraps(f)
def decorated(*args, **kwds):
with MyContextManager() as cm:
kwds['cm'] = cm
return f(*args, **kwds)
return decorated它可以使用(这里是一个单元):
class MyContextManagerTest(TestCase):
@patch_cm
def test_context_decorator(self, cm):
cm.do_something()
self.assertTrue(cm.done()) 这与以下相同:
def test_context_decorator(self):
with MyContextManager() as cm:
cm.do_something()
self.assertTrue(cm.done()) (我实际上使用的是一个带有参数的包装器,但这只是另外一个包装器.)
发布于 2020-02-24 20:39:02
不是的。在文档中明确提到了这一点。
注意,当使用上下文管理器作为函数装饰器时,还有一个额外的限制:无法访问
__enter__()的返回值。如果需要该值,则仍然需要使用显式with语句。
https://stackoverflow.com/questions/60383524
复制相似问题