我尝试使用Python的contextlib.ContextDecorator类编写上下文管理器装饰器。
有没有办法在上下文管理器中访问已修饰函数的参数?
以下是我正在做的事情的一个例子:
from contextlib import ContextDecorator
class savePen(ContextDecorator):
def __enter__(self):
self.prevPen = self.dc.GetPen() # AttributeError
return self
def __exit__(self, *exc):
self.dc.SetPen(self.prevPen)
return False
鉴于上述情况,这个:
@savePen()
def func(dc, param1, param2):
# do stuff, possibly changing the pen style
应该相当于:
def func(dc, param1, param2):
prevPen = dc.GetPen()
# do stuff, possibly changing the pen style
dc.SetPen(prevPen)
我已经搜索了contextlib的文档并且找不到任何有用的内容。
有谁知道如何访问装饰功能' ContextDecorator类中的属性?
正如@chepner在this response中所说,ContextDecorator是
的糖def func(dc, param1, param2):
with savePen():
...
并且它无法访问功能'参数。
但是,在这种情况下,with savePen()
内的任何内容都可以访问函数参数dc
,param1
和param2
。这让我觉得我应该能够使用ContextDecorator访问它们。
例如,这是有效的:
def func(dc, param1, param2):
with savePen():
print(param1)
答案 0 :(得分:1)
contextlib.contextmanager
似乎更合适。请注意,与其他任何内容一样,您无法从函数外部访问函数体的局部变量(无论如何都缺少内省黑客)。
@contextlib.contextmanager
def savePen(dc):
prevPen = dc.GetPen()
yield
dc.SetPen(prevPen)
with savePen(dc):
func(dc, param1, param2)
请注意,对于ContextDecorator
,上下文管理器实例化时不带参数,即
@savePen()
def func(dc, param1, param2):
# do stuff, possibly changing the pen style
是
的语法糖(根据文档)def func(dc, param1, param2):
with savePen():
...
所以没有办法告诉savePen
使用哪个对象(dc
)。
答案 1 :(得分:0)
我设法通过构建自己的装饰器,使用我之前在Python2中完成的东西来做到这一点。
我没有使用上下文管理器,只使用了this
结构。
这就是我提出的问题(我已经删除了使文档字符串正确的所有漏洞):
try...finally