只计算一次属性并多次使用结果(不同的方法)
Posted
技术标签:
【中文标题】只计算一次属性并多次使用结果(不同的方法)【英文标题】:Calculate property only once and use the result several times (different approaches) 【发布时间】:2017-12-18 19:06:50 【问题描述】:我尝试多次使用类方法的结果,而不进行获得结果所需的繁重计算。
我看到以下选项。你认为哪个是正确的,还是更 Pythonic?
各有什么优缺点?
尝试/排除方法
class Test:
def __init__(self, *args):
# do stuff
@property
def new_method(self):
try:
return self._new_property
except AttributeError:
# do some heavy calculations
return self._new_property
lru_cache 方法
from functools import lru_cache
class Test:
def __init__(self, *args):
# do stuff
@property
@lru_cache()
def new_method(self):
# do some heavy calculations
return self._new_property
Django 的 cache_property 方法
from django.utils.functional import cached_property
class Test:
def __init__(self, *args):
# do stuff
@cached_property
def new_method(self):
# do some heavy calculations
return self._new_property
【问题讨论】:
好问题。 Related SO question 强烈支持 lru_cache。因为你不使用任何参数,直觉上,我会继续使用普通的 try-catch。 这能回答你的问题吗? Caching class attributes in Python 【参考方案1】:Python 3.8 更新:您现在可以使用functools.cached_property
from functools import cached_property
class Test:
def __init__(self, *args):
# do stuff
@cached_property
def new_method(self):
# do some heavy calculations
return self._new_property
【讨论】:
【参考方案2】:Try/except 简单易读,但总有一天你会想要缓存另一个属性,对吧?所以有一天你可能会编写自己的缓存属性。
lru_cache 使用标准库是个好主意,但由于您不需要 lru 缓存,因此可能会产生开销。
Django 的 cache_property 完全按照您的意愿工作,而且非常简单。它在 werkzeug 中具有类似功能(因此 Flask 用户也熟悉它),很容易找到来源,所以它可能是您的不错选择。
【讨论】:
是的,Django的cache_property很简单。我做了一些测试,它的速度非常快,比 try/except 快 2.5。如果使用它没有缺点,我想我会使用它。我的班级有几个属性,也许代码会更干净。以上是关于只计算一次属性并多次使用结果(不同的方法)的主要内容,如果未能解决你的问题,请参考以下文章