Python functools lru_cache with instance methods: release object(带有实例方法的Python函数工具lru_cache:Release对象)
本文介绍了带有实例方法的Python函数工具lru_cache:Release对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
如何在不泄漏内存的情况下在类内使用functools.lru_cache
?
在下面的最小示例中,foo
实例将不会被释放,尽管它超出作用域并且没有引用对象(除lru_cache
以外)。
from functools import lru_cache
class BigClass:
pass
class Foo:
def __init__(self):
self.big = BigClass()
@lru_cache(maxsize=16)
def cached_method(self, x):
return x + 5
def fun():
foo = Foo()
print(foo.cached_method(10))
print(foo.cached_method(10)) # use cache
return 'something'
fun()
但是foo
,因此foo.big
(aBigClass
)仍然有效
import gc; gc.collect() # collect garbage
len([obj for obj in gc.get_objects() if isinstance(obj, Foo)]) # is 1
这意味着Foo
/BigClass
实例仍驻留在内存中。即使删除Foo
(delFoo
)也不会释放它们。
为什么lru_cache
要保留实例?缓存不是使用某些哈希而不是实际对象吗?
建议在类内使用lru_cache
的方式是什么?
我知道两种解决方法: Use per instance caches或make the cache ignore object(但可能导致错误结果)
推荐答案
这不是最干净的解决方案,但对程序员完全透明:
import functools
import weakref
def memoized_method(*lru_args, **lru_kwargs):
def decorator(func):
@functools.wraps(func)
def wrapped_func(self, *args, **kwargs):
# We're storing the wrapped method inside the instance. If we had
# a strong reference to self the instance would never die.
self_weak = weakref.ref(self)
@functools.wraps(func)
@functools.lru_cache(*lru_args, **lru_kwargs)
def cached_method(*args, **kwargs):
return func(self_weak(), *args, **kwargs)
setattr(self, func.__name__, cached_method)
return cached_method(*args, **kwargs)
return wrapped_func
return decorator
它采用与lru_cache
完全相同的参数,并且工作方式完全相同。但是,它从不将self
传递给lru_cache
,而是使用每个实例的lru_cache
。
这篇关于带有实例方法的Python函数工具lru_cache:Release对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
沃梦达教程
本文标题为:带有实例方法的Python函数工具lru_cache:Release对象


猜你喜欢
- 沿轴计算直方图 2022-01-01
- pytorch 中的自适应池是如何工作的? 2022-07-12
- python-m http.server 443--使用SSL? 2022-01-01
- padding='same' 转换为 PyTorch padding=# 2022-01-01
- 分析异常:路径不存在:dbfs:/databricks/python/lib/python3.7/site-packages/sampleFolder/data; 2022-01-01
- 如何在 Python 的元组列表中对每个元组中的第一个值求和? 2022-01-01
- 如何在 python3 中将 OrderedDict 转换为常规字典 2022-01-01
- 使用Heroku上托管的Selenium登录Instagram时,找不到元素';用户名'; 2022-01-01
- 如何将一个类的函数分成多个文件? 2022-01-01
- python check_output 失败,退出状态为 1,但 Popen 适用于相同的命令 2022-01-01