I'm trying to cache the function expand
by only its first argument. I don't care about the values of the other arguments for the purpose of caching.
Since the other arguments are dicts, they aren't cacheable, so I've defined a class to contain these arguments whose hash always returns 0, so it should be ignored by the caching function.
I have added some cutdown code below. I'm on Python version 3.5.2.
class Node:
def __init__(self, value):
self.value = value
def expand(self, a1, a2):
return '{},{},{}'.format(self.value, a1, a2)
class ExpandArgs:
def __init__(self, a1, a2):
self.a1 = a1
self.a2 = a2
def __hash__(self):
# We don't care about the hash, but it's required for caching
return 0
@functools.lru_cache(maxsize=None) # hash of args is always 0, so it should be ignored, and the hash of node should be used as the cache key
def expand(node, args):
a1 = args.a1
a2 = args.a2
return node.expand(a1, a2)
e1 = ExpandArgs({}, {})
e2 = ExpandArgs({}, {})
print(hash(e1)) # 0
print(hash(e2)) # 0
node = Node(123)
print(expand.cache_info()) # CacheInfo(hits=0, misses=0, maxsize=None, currsize=0)
expand(node, e1)
print(expand.cache_info()) # CacheInfo(hits=0, misses=1, maxsize=None, currsize=1)
expand(node, e2)
print(expand.cache_info()) # CacheInfo(hits=0, misses=2, maxsize=None, currsize=2)
expand(node, e1)
print(expand.cache_info()) # CacheInfo(hits=1, misses=2, maxsize=None, currsize=2)
expand(node, e2)
print(expand.cache_info()) # CacheInfo(hits=2, misses=2, maxsize=None, currsize=2)
Since hash(e1) == hash(e2)
, I would expect the second call to expand()
to hit the cached value for e1
, but it misses.
Why don't I get 1 cache miss, and 3 cache hits for the above code?