属性 getter 和上下文管理器

Property getter and context manager

我想定义一个 属性,无论何时调用它,它都是在上下文管理器中完成的。说吧,我开始于:

@property
def hangar(self):
    return self._hangar

每当写下代码时:

res = some_function(self.hangar)

我希望它被评价为:

with pandas.HDFStore(...) as hangar:
    some_function(self.hangar)

有什么想法吗?

正如您从评论中看到的那样,您需要的是某种程度上 "inside out" 上下文管理器的通常工作方式。

但这并不能阻止你让你的函数 call/attribute 检索 "inside out" 完全一样:你所需要的只是,而不是使用 'property' 调用所需的方法,传递目标函数作为参数。

这边的一些东西:

def context_property(method):
    def wrapper(self, target, *args, **kw):
        path = method(self)
        with pandads.HDFStore(path) as context:
            result = target(context, *args, **kw)
        return result
    return wrapper

class MyClass:
    @context_property
    def hangar(self):
        return "path_to_hdfstore"

    def do_stuff(self):
        ...
        value = self.hangar(some_function)
        ...

并且 some_function 将在上下文管理器中 运行。如果你需要使上下文管理器本身通用,而不是总是 "pandas.HDFStore",你可以在装饰器上多放一个级别来配置它。

接受的答案是正确的,但有类似的问题,我选择创建一个 属性,它也是一个上下文管理器。所以想法是使用属性作为上下文管理器 always.

你的情况:

@property
def hangar(self):
    return pandas.HDFStore(...)

然后你使用with:

with self.hangar as hangar:
   res = some_function(hangar)

这允许您更改 hangar 非上下文管理器的定义(例如在子类中)。在这种情况下,您需要装饰您的方法:

@property
@contextmanager
def hangar(self):
    yield self._hangar

而且它还在工作。请记住,装饰器顺序 很重要 ,因为 yield 而不是 return