functools.lru_cache 具有相同哈希的两个对象之间的差异

发布于 2025-01-12 17:20:05 字数 1564 浏览 6 评论 0原文

阅读 https://github.com/python/cpython 的代码后/blob/master/Lib/functools.py 我认为 lru_cache 使用哈希从函数参数构建密钥,所以如果我两个对象具有相同的哈希 他们应该是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 正在检测 m1am1b 是不同的,即使它们具有相同的 hash< /代码>。

我该怎么做才能使 lru_cache 不区分具有相同 __init__ 参数的 MyClass 的两个实例?

After reading the code of https://github.com/python/cpython/blob/master/Lib/functools.py I thought that lru_cache use hash to build a key from the function arguments, so if I two object have the same hash they should be the same for lru_cache.

If you run this code:

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>,), {})

you can see that lru_cache is detecting that m1a and m1b are different even they have the same hash.

What can I do in order that lru_cache doesn't differentiate between two instances of MyClass with same __init__ arguments?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

流星番茄 2025-01-19 17:20:05

lru_cache 首先使用 __hash__ 然后检查 __eq__
将 __eq__ 方法添加到您的类中

    def __eq__(self, other):
        return type(self) == type(other) and self._init_args == other._init_args

lru_cache uses __hash__ at first then it checks __eq__
Add __eq__ method to your class

    def __eq__(self, other):
        return type(self) == type(other) and self._init_args == other._init_args
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文