有没有一种简单的方法可以在对象级别上记住(和刷新)Python上的属性? [英] Is there an easy way to memoize (and flush) properties on Python at object level?

查看:59
本文介绍了有没有一种简单的方法可以在对象级别上记住(和刷新)Python上的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种缓存对象属性的方法.就我而言,我假设对象可以随时间变化,因此该属性的备注值应可刷新.在纯python中,我希望具有以下行为:

I'm looking for a way to cache properties of an object. In my case, I suppose the object can change over the time, so the memoized value for the property should be flushable. In pure python, I want to have a behaviour like:

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 ,然后进行分配和刷新以获取记录的行为.

Then, as you can see, I want to cache the Foo.bar property. My approach was to define a private property initialised as None and then assigned and flushed to obtain a memoized behaviour.

现在,我的问题是,是否有某种方法,库,方法或技术可以在无需拥有私有属性的情况下获得此行为(假设您在类中倾向于记忆的属性).

我正在从标准库(@lru_cache()装饰器(以及最新的 @cached_property )的信息.python.org/3/library/functools.html"rel =" nofollow noreferrer> https://docs.python.org/3/library/functools.html ),但我意识到cache_clear()方法删除该类的所有实例的备注值.

I was reading about the @lru_cache() decorator (and the newest @cached_property) from the Standard Library (https://docs.python.org/3/library/functools.html), but I realised that the cache_clear() method removes the memoized values for all the instances of the class.

我本以为一种可能的解决方案可能是使用不可变对象,但这种解决方案并非我所希望的,因为在某些情况下,我只想刷新属性备注之一.

I was thinking that one possible solution could be to use immutable objects, but that solution is not as I want, because probably there will be situations in which I only want to flush one of the properties memoization.

推荐答案

感谢@sanyash对问题评论的讨论.

有一个 cached_property 包( https://pypi.org/project/cached-property/)来提供请求的行为.使用 cached_property 的示例如下:

There is a cached_property package (https://pypi.org/project/cached-property/) that provides the requested behaviour. The example using cached_property is as follows:

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".

这篇关于有没有一种简单的方法可以在对象级别上记住(和刷新)Python上的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆