Python - 什么是懒惰属性?

时间:2014-07-11 18:26:00

标签: python python-2.7 properties webapp2

在线查看webapp2文档时,我找到了有关装饰器webapp2.cached_property的信息(可在https://webapp-improved.appspot.com/api/webapp2.html#webapp2.cached_property找到)。

在文档中,它说:

  

将函数转换为惰性属性的装饰器。

我的问题是:

  1. 什么是懒惰的财产?
  2. 谢谢!

1 个答案:

答案 0 :(得分:7)

第一次通话后,它是一个property装饰器。它允许您自动缓存计算值。

standard library @property decoratordata descriptor object并且总是被调用,即使同名实例上有属性。

另一方面,@cached_property装饰器具有__get__方法,这意味着如果已存在具有相同名称的属性,则不会调用它。它通过在第一次调用时在实例上设置具有相同名称的属性来使用它。

在名为@cached_property的实例上给出bar - 装饰foo方法,会发生以下情况:

  • Python解析foo.bar。在实例上找不到bar属性。

  • Python在类中找到bar描述符,并在其上调用__get__

  • cached_property __get__方法调用已修饰的bar方法。

  • bar方法会计算某些内容,并返回字符串'spam'

  • cached_property __get__方法获取返回值并在实例上设置新属性bar; foo.bar = 'spam'

  • cached_property __get__方法返回'spam'返回值。

  • 如果再次要求foo.bar,Python会在实例上找到bar属性,并从此处开始使用。

另见source code for the original Werkzeug implementation

# implementation detail: this property is implemented as non-data
# descriptor.  non-data descriptors are only invoked if there is
# no entry with the same name in the instance's __dict__.
# this allows us to completely get rid of the access function call
# overhead.  If one choses to invoke __get__ by hand the property
# will still work as expected because the lookup logic is replicated
# in __get__ for manual invocation.