当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python Django cached_property用法及代码示例


本文介绍 django.utils.functional.cached_property 的用法。

声明

class cached_property(func, name=None)[source]

@cached_property 装饰器使用单个 self 参数作为属性缓存方法的结果。只要实例存在,缓存的结果就会一直存在,因此如果传递了实例并且随后调用了函数,则将返回缓存的结果。

考虑一个典型情况,在将模型实例放入上下文之前,视图可能需要调用模型的方法来执行一些计算,其中模板可能会再次调用该方法:

# the model
class Person(models.Model):

    def friends(self):
        # expensive computation
        ...
        return friends

# in the view:
if person.friends():
    ...

在模板中,您将拥有:

{% for friend in person.friends %}

在这里,friends() 将被调用两次。由于视图中的实例person和模板是一样的,用@cached_property装饰friends()方法可以避免这种情况:

from django.utils.functional import cached_property

class Person(models.Model):

    @cached_property
    def friends(self):
        ...

请注意,由于该方法现在是一个属性,因此在 Python 代码中需要适当地访问它:

# in the view:
if person.friends:
    ...

缓存的值可以视为实例的普通属性:

# clear it, requiring re-computation next time it's called
del person.friends # or delattr(person, "friends")

# set a value manually, that will persist on the instance until cleared
person.friends = ["Huckleberry Finn", "Tom Sawyer"]

由于说明符协议的工作方式,在尚未访问的 cached_property 上使用 del (或 delattr )会引发 AttributeError

除了提供潜在的性能优势之外,@cached_property 还可以确保属性的值在实例的生命周期内不会发生意外变化。这可能发生在计算基于 datetime.now() 的方法上,或者如果在同一实例上后续调用方法之间的短暂间隔内某个其他进程将更改保存到数据库中。

您可以制作方法的缓存属性。例如,如果您有一个昂贵的 get_friends() 方法并且希望允许在不检索缓存值的情况下调用它,您可以编写:

friends = cached_property(get_friends)

虽然 person.get_friends() 将在每次调用时重新计算好友,但缓存属性的值将持续存在,直到您将其删除,如上所述:

x = person.friends         # calls first time
y = person.get_friends()   # calls again
z = person.friends         # does not call
x is z                     # is True

相关用法


注:本文由纯净天空筛选整理自djangoproject.com大神的英文原创作品 django.utils.functional.cached_property。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。