簡體   English   中英

如何在 Python 中記住一個屬性?

[英]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.aself.b沒有改變,那么我們不需要繼續重新計算屬性。

僅當self.aself.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

也使用ab屬性並清除 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM