Python - 什么是懒惰属性?

7 python properties python-2.7 webapp2

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

在文档中,它说:

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

我的问题是:

  1. 什么是懒惰的财产?

谢谢!

Mar*_*ers 9

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

标准库@property的装饰是一个数据描述对象,并一直叫,即使有同名的实例的属性.

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

给定一个名为的实例的@cached_property-decorated 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在实例上找到该属性,并从此处开始使用该属性.

另请参阅原始Werkzeug实现源代码:

# 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.
Run Code Online (Sandbox Code Playgroud)

  • @martineau:是的,谢谢你让我回答这个问题。我在我的答案中添加了对该版本的简短介绍。 (3认同)
  • Python-3.8 中添加了 `functools.cached_property`。 (2认同)