functools.lru_cache 具有相同哈希值的两个对象之间的差异
functools.lru_cache difference between two object with same hash
阅读 https://github.com/python/cpython/blob/master/Lib/functools.py 的代码后,我认为 lru_cache
使用散列从函数参数构建一个键,所以如果我的两个对象具有相同的 hash
它们应该是lru_cache.
也一样
如果您运行此代码:
from functools import lru_cache
COUNT=0
@lru_cache(maxsize=None)
def fnc(*args, **kvargs):
global COUNT
COUNT=COUNT+1
return COUNT, hash(args[0]), args ,kvargs
class MyClass:
def __init__(self, *args, **kvargs):
self._init_args=(args, frozenset(kvargs.items()))
def __hash__(self):
return hash(self._init_args)
m1a = MyClass(1)
m2a = MyClass(2)
m1b = MyClass(1)
m2b = MyClass(2)
fnc(m1a) # Output: (1, -7270110455953140331, (<__main__.MyClass object at 0x7fb14b540710>,), {})
fnc(m1a) # Output: (1, -7270110455953140331, (<__main__.MyClass object at 0x7fb14b540710>,), {})
fnc(m2a) # Output: (2, 7567087542259278010, (<__main__.MyClass object at 0x7fb14b540810>,), {})
fnc(m2a) # Output: (2, 7567087542259278010, (<__main__.MyClass object at 0x7fb14b540810>,), {})
fnc(m1b) # Output: (3, -7270110455953140331, (<__main__.MyClass object at 0x7fb14b540610>,), {})
fnc(m2b) # Output: (4, 7567087542259278010, (<__main__.MyClass object at 0x7fb14b540b50>,), {})
你可以看到 lru_cache
正在检测 m1a
和 m1b
不同,即使它们具有相同的 hash
。
我该怎么做才能使 lru_cache
不区分具有相同 __init__
个参数的两个 MyClass 实例?
lru_cache 首先使用 __hash__
然后检查 __eq__
将 __eq__
方法添加到您的 class
def __eq__(self, other):
return type(self) == type(other) and self._init_args == other._init_args
阅读 https://github.com/python/cpython/blob/master/Lib/functools.py 的代码后,我认为 lru_cache
使用散列从函数参数构建一个键,所以如果我的两个对象具有相同的 hash
它们应该是lru_cache.
如果您运行此代码:
from functools import lru_cache
COUNT=0
@lru_cache(maxsize=None)
def fnc(*args, **kvargs):
global COUNT
COUNT=COUNT+1
return COUNT, hash(args[0]), args ,kvargs
class MyClass:
def __init__(self, *args, **kvargs):
self._init_args=(args, frozenset(kvargs.items()))
def __hash__(self):
return hash(self._init_args)
m1a = MyClass(1)
m2a = MyClass(2)
m1b = MyClass(1)
m2b = MyClass(2)
fnc(m1a) # Output: (1, -7270110455953140331, (<__main__.MyClass object at 0x7fb14b540710>,), {})
fnc(m1a) # Output: (1, -7270110455953140331, (<__main__.MyClass object at 0x7fb14b540710>,), {})
fnc(m2a) # Output: (2, 7567087542259278010, (<__main__.MyClass object at 0x7fb14b540810>,), {})
fnc(m2a) # Output: (2, 7567087542259278010, (<__main__.MyClass object at 0x7fb14b540810>,), {})
fnc(m1b) # Output: (3, -7270110455953140331, (<__main__.MyClass object at 0x7fb14b540610>,), {})
fnc(m2b) # Output: (4, 7567087542259278010, (<__main__.MyClass object at 0x7fb14b540b50>,), {})
你可以看到 lru_cache
正在检测 m1a
和 m1b
不同,即使它们具有相同的 hash
。
我该怎么做才能使 lru_cache
不区分具有相同 __init__
个参数的两个 MyClass 实例?
lru_cache 首先使用 __hash__
然后检查 __eq__
将 __eq__
方法添加到您的 class
def __eq__(self, other):
return type(self) == type(other) and self._init_args == other._init_args