我想以这样的方式定义一个属性:无论何时调用它,它都是在上下文管理器中完成的。说,我从:
开始res = some_function(self.hangar)
每当我写下代码时,
with pandas.HDFStore(...) as hangar:
some_function(self.hangar)
我希望将其评估为:
{{1}}
有什么想法吗?
答案 0 :(得分:1)
接受的答案是正确的,但有类似的问题我选择创建一个属性,它也是一个上下文管理器。因此,我们的想法是将该属性用作上下文管理器始终。
就你而言:
@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
。
答案 1 :(得分:0)
正如您从评论中看到的那样,您需要的内容与内容管理器的常用方式有些“内外”。
但是这并不能阻止你使你的函数调用/属性检索“内向外”完全相同:所有你需要的是,而不是使用'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”,你可以在装饰器上再添加一个级别来配置它。