Wie kann ich den lru_cache der functools in Klassen verwenden, ohne dass Speicher verloren geht? Im folgenden minimalen Beispiel wird die foo
Instanz nicht freigegeben, obwohl sie den Gültigkeitsbereich verlässt und keinen Referrer hat (außer dem lru_cache).Python functools lru_cache mit Klassenmethoden: release object
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()
Aber foo
und damit foo.big
(a BigClass
) sind noch am Leben
import gc; gc.collect() # collect garbage
len([obj for obj in gc.get_objects() if isinstance(obj, Foo)]) # is 1
Das bedeutet, dass Foo/BigClass Instanzen noch im Speicher befinden. Selbst das Löschen von Foo
(del Foo
) wird sie nicht freigeben.
Warum hält sich lru_cache überhaupt an der Instanz fest? Verwendet der Cache keinen Hash und nicht das eigentliche Objekt?
Was ist die empfohlene Methode Verwenden Sie lru_caches in Klassen?
Ich weiß von zwei Lösungen: Use per instance caches oder make the cache ignore object (was zu falschen Ergebnissen führen könnte, obwohl)