有没有一种简单的方法可以在对象级别记忆(和刷新)Python 上的属性?
Is there an easy way to memoize (and flush) properties on Python at object level?
我正在寻找一种缓存对象属性的方法。在我的例子中,我想对象会随着时间的推移而改变,所以 属性 的记忆值应该是可刷新的。在纯 python 中,我希望有这样的行为:
class Foo:
def __init__(self, text: str):
self._text = text
self._bar = None
def flush(self):
self._bar = None
def update_text(self, text: str):
self._text = text
self.flush()
@property
def bar(self):
if self._bar is None:
print('Computing bar...')
self._bar = f'Computation with "{self._text}".'
return self._bar
foo1 = Foo('Dog')
foo2 = Foo('Fish')
print(foo1.bar)
# Computing bar...
# Computation with "Dog".
print(foo1.bar)
# Computation with "Dog".
print(foo2.bar)
# Computing bar...
# Computation with "Fish".
print(foo2.bar)
# Computation with "Fish".
foo1.update_text('Cat')
print(foo1.bar)
# Computing bar...
# Computation with "Cat".
print(foo1.bar)
# Computation with "Cat".
print(foo2.bar)
# Computation with "Fish".
然后,如您所见,我想缓存 Foo.bar
属性。我的方法是定义一个初始化为 None
的私有 属性,然后分配并刷新以获得记忆行为。
现在,我的问题是是否有一些方法、库、方法或技术可以在不需要私有 属性 的情况下获得这种行为(假设您有一些可记忆的属性在 class).
我正在阅读标准库 (https://docs.python.org/3/library/functools.html) 中的 @lru_cache()
装饰器(以及最新的 @cached_property
),但我意识到 cache_clear()
方法删除了class.
的所有实例的记忆值
我在想一种可能的解决方案是使用不可变对象,但该解决方案并不如我所愿,因为可能会出现我只想刷新其中一个属性记忆的情况。
感谢@sanyash 对问题评论的讨论。
有一个 cached_property
包 (https://pypi.org/project/cached-property/) 提供了请求的行为。使用cached_property
的例子如下:
from cached_property import cached_property
class Foo:
def __init__(self, text: str):
self._text = text
def flush(self):
del self.__dict__['bar']
def update_text(self, text: str):
self._text = text
self.flush()
@cached_property
def bar(self):
print('Computing bar...')
return f'Computation with "{self._text}".'
foo1 = Foo('Dog')
foo2 = Foo('Fish')
print(foo1.bar)
# Computing bar...
# Computation with "Dog".
print(foo1.bar)
# Computation with "Dog".
print(foo2.bar)
# Computing bar...
# Computation with "Fish".
print(foo2.bar)
# Computation with "Fish".
foo1.update_text('Cat')
print(foo1.bar)
# Computing bar...
# Computation with "Cat".
print(foo1.bar)
# Computation with "Cat".
print(foo2.bar)
# Computation with "Fish".
cached_property
完美解决缓存属性
如果您对函数有类似的担忧,methodtools 适用于每个实例。
import methodtools
class Foo:
@methodtools.lru_cache(maxsize=128)
def bar(self, a, b, c):
return something_using_parameters
我正在寻找一种缓存对象属性的方法。在我的例子中,我想对象会随着时间的推移而改变,所以 属性 的记忆值应该是可刷新的。在纯 python 中,我希望有这样的行为:
class Foo:
def __init__(self, text: str):
self._text = text
self._bar = None
def flush(self):
self._bar = None
def update_text(self, text: str):
self._text = text
self.flush()
@property
def bar(self):
if self._bar is None:
print('Computing bar...')
self._bar = f'Computation with "{self._text}".'
return self._bar
foo1 = Foo('Dog')
foo2 = Foo('Fish')
print(foo1.bar)
# Computing bar...
# Computation with "Dog".
print(foo1.bar)
# Computation with "Dog".
print(foo2.bar)
# Computing bar...
# Computation with "Fish".
print(foo2.bar)
# Computation with "Fish".
foo1.update_text('Cat')
print(foo1.bar)
# Computing bar...
# Computation with "Cat".
print(foo1.bar)
# Computation with "Cat".
print(foo2.bar)
# Computation with "Fish".
然后,如您所见,我想缓存 Foo.bar
属性。我的方法是定义一个初始化为 None
的私有 属性,然后分配并刷新以获得记忆行为。
现在,我的问题是是否有一些方法、库、方法或技术可以在不需要私有 属性 的情况下获得这种行为(假设您有一些可记忆的属性在 class).
我正在阅读标准库 (https://docs.python.org/3/library/functools.html) 中的 @lru_cache()
装饰器(以及最新的 @cached_property
),但我意识到 cache_clear()
方法删除了class.
我在想一种可能的解决方案是使用不可变对象,但该解决方案并不如我所愿,因为可能会出现我只想刷新其中一个属性记忆的情况。
感谢@sanyash 对问题评论的讨论。
有一个 cached_property
包 (https://pypi.org/project/cached-property/) 提供了请求的行为。使用cached_property
的例子如下:
from cached_property import cached_property
class Foo:
def __init__(self, text: str):
self._text = text
def flush(self):
del self.__dict__['bar']
def update_text(self, text: str):
self._text = text
self.flush()
@cached_property
def bar(self):
print('Computing bar...')
return f'Computation with "{self._text}".'
foo1 = Foo('Dog')
foo2 = Foo('Fish')
print(foo1.bar)
# Computing bar...
# Computation with "Dog".
print(foo1.bar)
# Computation with "Dog".
print(foo2.bar)
# Computing bar...
# Computation with "Fish".
print(foo2.bar)
# Computation with "Fish".
foo1.update_text('Cat')
print(foo1.bar)
# Computing bar...
# Computation with "Cat".
print(foo1.bar)
# Computation with "Cat".
print(foo2.bar)
# Computation with "Fish".
cached_property
完美解决缓存属性
如果您对函数有类似的担忧,methodtools 适用于每个实例。
import methodtools
class Foo:
@methodtools.lru_cache(maxsize=128)
def bar(self, a, b, c):
return something_using_parameters