Python 为什么functools.lru\u cache在使用普通方法时不调用cache\uu\u
我一直在尝试使Python 为什么functools.lru\u cache在使用普通方法时不调用cache\uu\u,python,caching,magic-methods,Python,Caching,Magic Methods,我一直在尝试使functools.lru\u缓存特定于中所述的实例,但在\uuuu调用方法上使用它们的解决方案时失败 class test: def __init__(self): self.method = lru_cache()(self.method) self.__call__ = lru_cache()(self.__call__) def method(self, x): print('method', end=' '
functools.lru\u缓存
特定于中所述的实例,但在\uuuu调用
方法上使用它们的解决方案时失败
class test:
def __init__(self):
self.method = lru_cache()(self.method)
self.__call__ = lru_cache()(self.__call__)
def method(self, x):
print('method', end=' ')
return x
def __call__(self, x):
print('__call__', end=' ')
return x
b = test()
# b.method is cached as expected
print(b.method(1)) # method 1
print(b.method(1)) # 1
# __call__ is executed every time
print(b(1)) # __call__ 1
print(b(1)) # __call__ 1
因此,当使用此方法包装时,\uuuuuu调用
的结果不会被缓存。\uuuuu call\uuuuu
上的缓存甚至不注册已调用的函数,不可破坏的值不会抛出错误
print(b.method.cache_info())
# CacheInfo(hits=1, misses=1, maxsize=128, currsize=1)
print(b.__call__.cache_info())
# CacheInfo(hits=0, misses=0, maxsize=128, currsize=0)
print(b.call({})) # __call__ {}
print(b.method({})) # ... TypeError: unhashable type: 'dict'
这是由于类属性和实例属性之间的差异造成的。当访问属性(例如
方法
)时,python首先检查实例属性。如果您没有分配给self.method
,它将找不到。然后检查类属性,这相当于self.\uu class\uuu.method
。分配给仅更新实例属性的self.method
,不会更改此函数的值
然而,
b(1)
变成了b.\uu类
。\uu调用(b,1),它使用了\uu调用
和b的原始类定义。由于方法使用了实例定义,因此它将以与方法
相同的方式缓存。原始答案非常好
我附上这个问题的另一个解决办法。
methodtools.lru\u缓存将按预期工作
从methodtools导入lru\U缓存
课堂测试:
@lru_缓存
定义调用(self,x):
打印(“调用”,结束=”)
返回x
它需要通过pip安装methodtools
:
pip install methodtools我试过编写代码,如果将@lru\u cache
decorator应用于\uuu call\uuuu
,它可以正常工作,但对于您的情况,您在初始化时将\uuuu call\uuuuu
分配给self,因此\uuu call\uuuuu\uu
的lru版本被添加到self中,没有实际更改\uuuu call\uuuu
方法。@Enix如果您指的是正常装饰\uuuu call\uuuuuu
,那么对一个实例来说是可以的,但一旦有两个实例,缓存就会共享,在一个实例上重置缓存会在另一个实例上重置,因此使用装饰器通常不起作用。(我尽量不提出关于如何拥有实例特定缓存的问题,因为链接的问题涵盖了这一点)