gpt4 book ai didi

python - 第一次访问后缓存返回值的类方法的装饰器

转载 作者:IT老高 更新时间:2023-10-28 22:22:18 27 4
gpt4 key购买 nike

我的问题,为什么

我正在尝试为类方法 @cachedproperty 编写装饰器。我希望它表现得如此,当第一次调用该方法时,该方法被它的返回值替换。我还希望它表现得像 @property 这样就不需要显式调用它。基本上,它应该与 @property 没有区别,只是 它更快,因为它只计算一次值然后存储它。我的想法是,这不会像在 __init__ 中定义它那样减慢实例化速度。这就是我想要这样做的原因。

我尝试了什么

首先,我尝试覆盖propertyfget方法,但它是只读的。

接下来,我想我会尝试实现一个确实需要第一次调用但随后缓存值的装饰器。这不是我永远不需要调用的属性类型装饰器的最终目标,但我认为这将是一个更简单的问题,首先要解决。换句话说,对于一个稍微简单的问题,这是一个行不通的解决方案。

我试过了:

def cachedproperty(func):
""" Used on methods to convert them to methods that replace themselves
with their return value once they are called. """
def cache(*args):
self = args[0] # Reference to the class who owns the method
funcname = inspect.stack()[0][3] # Name of the function, so that it can be overridden.
setattr(self, funcname, func()) # Replace the function with its value
return func() # Return the result of the function
return cache

但是,这似乎不起作用。我对此进行了测试:

>>> class Test:
... @cachedproperty
... def test(self):
... print "Execute"
... return "Return"
...
>>> Test.test
<unbound method Test.cache>
>>> Test.test()

但是我收到一个关于类如何没有将自身传递给方法的错误:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method cache() must be called with Test instance as first argument (got nothing instead)

在这一点上,我和我对深度 Python 方法的有限知识非常困惑,我不知道我的代码哪里出了问题或如何修复它。 (我之前从未尝试过写装饰器)

问题

如何编写一个装饰器,在第一次访问时返回调用类方法的结果(如 @property 那样),并为所有后续查询替换为缓存值?

我希望这个问题不会太令人困惑,我试图尽可能地解释它。

最佳答案

如果您不介意其他解决方案,我建议您使用 lru_cache

例如

from functools import lru_cache
class Test:
@property
@lru_cache(maxsize=None)
def calc(self):
print("Calculating")
return 1

预期输出

In [2]: t = Test()

In [3]: t.calc
Calculating
Out[3]: 1

In [4]: t.calc
Out[4]: 1

关于python - 第一次访问后缓存返回值的类方法的装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36684319/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com