首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >上下文管理器是访问已生成对象的装饰器。

上下文管理器是访问已生成对象的装饰器。
EN

Stack Overflow用户
提问于 2020-02-24 20:34:39
回答 2查看 473关注 0票数 1

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

代码语言:javascript
复制
with MyContextManager as cm:
    cm.do_something()

我知道,如果使用contextlib.ContextDecorator创建一个简单的上下文管理器,它就可以变成一个装饰器。如果使用装饰器,也可以访问上下文管理器生成的对象吗?例如,考虑到上面的上下文管理器,如下所示:

代码语言:javascript
复制
@cmdecorator
def my_function(self, cm):
    cm.do_something

我不能让它起作用。要么我错过了一些微不足道的东西(希望如此),要么这是不可能的.最后它只是语法糖,但如果可能的话,我很感兴趣。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-25 19:45:54

要回答我自己的问题:虽然没有自动机制,但是编写一个精确的装饰器(使用硬编码的关键字参数)是非常容易的:

代码语言:javascript
复制
def patch_cm(f):
    @functools.wraps(f)
    def decorated(*args, **kwds):
        with MyContextManager() as cm:
            kwds['cm'] = cm
            return f(*args, **kwds)

    return decorated

它可以使用(这里是一个单元):

代码语言:javascript
复制
class MyContextManagerTest(TestCase):
    @patch_cm
    def test_context_decorator(self, cm):
        cm.do_something()
        self.assertTrue(cm.done()) 

这与以下相同:

代码语言:javascript
复制
def test_context_decorator(self):
    with MyContextManager() as cm:
       cm.do_something()
       self.assertTrue(cm.done()) 

(我实际上使用的是一个带有参数的包装器,但这只是另外一个包装器.)

票数 2
EN

Stack Overflow用户

发布于 2020-02-24 20:39:02

不是的。在文档中明确提到了这一点。

注意,当使用上下文管理器作为函数装饰器时,还有一个额外的限制:无法访问__enter__()的返回值。如果需要该值,则仍然需要使用显式with语句。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60383524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档