我有一个对象的上下文管理器,可以与open
上下文管理器类似使用,例如
with MyContextManager as cm:
cm.do_something()
我知道,如果使用contextlib.ContextDecorator
创建一个简单的上下文管理器,则可以将其变成装饰器。如果使用装饰器,是否还可以访问从上下文管理器生成的对象?例如。给定上面的上下文管理器,类似:
@cmdecorator
def my_function(self, cm):
cm.do_something
我无法解决这个问题。我可能缺少一些琐碎的东西(希望如此),或者这根本不可能……最后只是语法糖,但我对是否有可能感兴趣。
没有documentation中明确提到了这一点。
[请注意,将上下文管理器用作函数修饰符时,还有一个限制:无法访问
__enter__()
的返回值。如果需要该值,那么仍然有必要使用显式的with
语句。
要回答我自己的问题:我使用了一种简单的解决方法(经过硬编码的关键字参数),该解决方法足以满足我的用例:
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):
@patchfs
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())