我正在研究 Python 中的一些延迟加载属性装饰器,并且发生在这个示例中(http://code.activestate.com/recipes/363602-lazy-property-evaluation/ http://code.activestate.com/recipes/363602-lazy-property-evaluation/):
class Lazy(object):
def __init__(self, calculate_function):
self._calculate = calculate_function
def __get__(self, obj, _=None):
if obj is None:
return self
value = self._calculate(obj)
setattr(obj, self._calculate.func_name, value)
return value
# Sample use:
class SomeClass(object):
@Lazy
def someprop(self):
print 'Actually calculating value'
return 13
o = SomeClass()
o.someprop
o.someprop
我的问题是,这是如何运作的?我对装饰器的理解是它们必须是可调用的(因此实现的函数或调用__call__
), but Lazy
这里显然不是,如果我尝试Lazy(someFunc)()
它会按预期引发异常。我缺少什么?
当一个属性名为someprop
在实例上访问o
班级的SomeClass
, if SomeClass
包含一个描述符 named o
,那么该描述符的类的__get__
使用方法。有关描述符的更多信息,请参见本指南 http://users.rcn.com/python/download/Descriptor.htm。不要让这样的事实Lazy
从语法上讲,这里用作装饰器,让您看不到它的实例是描述符的事实,因为Lazy
本身有一个__get__
method.
装饰器语法
@Lazy
def someprop(self):
...
只不过是以下语法糖:
def someprop(self):
...
someprop = Lazy(someprop)
的限制Lazy
当它与装饰器语法一起使用或直接使用时没有什么不同:它必须接受someprop
(一个函数)作为其参数——对其返回的内容没有任何限制。这里,Lazy
是一个类,因此它返回自身的实例,并且有一个__get__
特殊方法,以便实例是一个描述符(因此当someprop
在实例上访问属性o
班级的SomeClass
)——这就是全部内容,不多也不少。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)