作为装饰器的上下文管理器,可以访问产生的对象

问题描述 投票:0回答:2

我有一个对象的上下文管理器,可以与open上下文管理器类似使用,例如

with MyContextManager as cm:
    cm.do_something()

我知道,如果使用contextlib.ContextDecorator创建一个简单的上下文管理器,则可以将其变成装饰器。如果使用装饰器,是否还可以访问从上下文管理器生成的对象?例如。给定上面的上下文管理器,类似:

@cmdecorator
def my_function(self, cm):
    cm.do_something

我无法解决这个问题。我可能缺少一些琐碎的东西(希望如此),或者这根本不可能……最后只是语法糖,但我对是否有可能感兴趣。

python python-decorators contextmanager
2个回答
1
投票

没有documentation中明确提到了这一点。

[请注意,将上下文管理器用作函数修饰符时,还有一个限制:无法访问__enter__()的返回值。如果需要该值,那么仍然有必要使用显式的with语句。


0
投票

要回答我自己的问题:我使用了一种简单的解决方法(经过硬编码的关键字参数),该解决方法足以满足我的用例:

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()) 
© www.soinside.com 2019 - 2024. All rights reserved.