获取python属性的属性
问题描述:
我有一个装饰器,它只是缓存返回值(在我的示例中称为@cached
),我希望将它与@property
结合使用。这通常工作正常。我遇到的问题出现在我尝试使用由@cached
添加的expire
属性。获取python属性的属性
def cached(f):
cache = [None]
def inner(*args, **kwargs):
if cache[0]:
cache[0] = f(*args, **kwargs)
return cache[0]
def expire():
cache[0] = None
inner.expire = expire
return inner
class Example(object):
@property
@cached
def something_expensive(self):
print("expensive")
return "hello"
e = Example()
e.something_expensive
e.something_expensive.expire()
我如何才能访问expire函数?在被@property
取代之后添加到该功能中。我明白为什么这不起作用我对解决该问题的方式感兴趣。
一些限制:
- 我不能改变
@cached
装饰它在图书馆,我不控制 - 我真的不想删除
@property
,因为我想在我的单元测试到期,他们做我的代码更好用。
一个解决方案,我认为是相当糟糕的是(因为在现实中,我有很多的属性,我想做到这一点的):
class Example(object):
@cached
def _something_expensive(self):
return "hello"
@property
def something_expensive(self):
return self._something_expensive()
答
您可以使用类字典访问:
type(e).__dict__['something_expensive'].fget.expire()
一般而言e.something_expensive
相当于:
type(e).__dict__['something_expensive'].__get__(e, type(e))
有关详细信息读了起来:Descriptor HowTo Guide
注意,expiry
功能你不从外部功能cached
功能None
设置cache
里面,你只需创建一个新的局部变量。您可能需要做这样的事情:
def expire():
del cache[:]
cache.append(None)
在Python 3中使用nonlocal
关键字更新cache
更简单。
非常感谢,我感谢帮助。缓存=无是一个打字错误的修复 – Nick