[英]How to memoize a property in Python?
考慮以下最小示例:
class Foo(object):
def __init__(self):
self.b = self.a = 1
@property
def sum(self):
print 'Recalculating sum'
return self.a + self.b
foo = Foo()
print foo.sum
print foo.sum # Prints 'Recalculating sum' even though neither a or b has changed since previous call
foo.a = 2
print foo.sum # a has been changed to 2 so recalculation is necessary
我想self.a
sum
以便如果self.a
和self.b
沒有改變,那么我們不需要繼續重新計算屬性。
僅當self.a
或self.b
發生變化時才應重新計算該屬性——有沒有一種簡單的方法可以做到這一點?
蟒蛇3:
from functools import lru_cache as memoized
@property
@memoized(maxsize=1)
def sum(self):
return self.a + self.b
蟒蛇 3.8
from functools import cache
@cached_property
def sum(self):
return self.a + self.b
也使用a
和b
屬性並清除 setter 中的緩存:
class Foo(object):
def __init__(self):
self.a = 1
self.b = 1
@property
def a(self):
return self._a
@a.setter
def a(self, value):
self._a = value
self._clearsum()
@property
def b(self):
return self._b
@b.setter
def b(self, value):
self._b = value
self._clearsum()
def _clearsum(self):
self._sum = None
@property
def sum(self):
if self._sum is None:
self._sum = self.a + self.b
return self._sum
或者如果你想要更通用的東西,你也可以檢查這個: 在對象中存儲計算值
編輯:最近有人建議在__init__
添加self._sum = None
以“避免訪問 sum 時出現錯誤”,但這實際上不是必需的 - __init__
調用a.setter
,它調用_clearsum
,它設置_sum
屬性,所以它是保證self._sum
將被創建。
有一個模塊可以做到這一點。 Pypi 鏈接在這里: https://pypi.org/project/memoized-property/對於上面的代碼,我使用模塊有這個:
In [2]: from memoized_property import memoized_property
In [3]: class test():
...: def __init__(self):
...: self.a = 0
...: self.b = 0
...: @memoized_property
...: def sum(self):
...: print('calculating...')
...: return self.a + self.b
In [4]: t=test()
calculating...
In [5]: t.sum
Out[5]: 0
In [7]: t.a=5
In [8]: t.sum
Out[8]: 0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.