You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何控制Python类方法的哈希值?及3.7与3.8版本差异疑问

控制Python类方法哈希值的问题解答

1. 3.7以上版本实现方法哈希相等的方案

要让不同实例的同名绑定方法哈希值相等,核心是让哈希计算逻辑仅依赖底层函数而非实例对象。可以通过拦截实例的属性获取过程,返回自定义的绑定方法对象来实现:

class BoundMethod:
    def __init__(self, instance, func):
        self.instance = instance
        self.func = func

    def __call__(self, *args, **kwargs):
        # 保留原方法的调用逻辑
        return self.func(self.instance, *args, **kwargs)

    def __hash__(self):
        # 哈希仅基于底层函数对象
        return hash(self.func)

class A:
    def hello(self, arg):
        print(arg)
    
    def __hash__(self):
        return 12345
    
    def __getattribute__(self, name):
        attr = super().__getattribute__(name)
        # 判断是否为实例的绑定方法(排除类方法、静态方法)
        if callable(attr) and hasattr(attr, '__func__'):
            return BoundMethod(self, attr.__func__)
        return attr

# 测试验证
a = A()
b = A()
print(hash(a.hello) == hash(b.hello))  # 输出 True

也可以用更轻量的方式,直接给动态创建的绑定方法替换__hash__逻辑:

class A:
    def hello(self, arg):
        print(arg)
    
    def __hash__(self):
        return 12345

a = A()
b = A()
# 手动替换绑定方法的哈希计算逻辑
a.hello.__hash__ = lambda: hash(a.hello.__func__)
b.hello.__hash__ = lambda: hash(b.hello.__func__)
print(hash(a.hello) == hash(b.hello))  # 输出 True

2. 版本间哈希结果变化的原因

Python 3.8对**绑定方法(bound method)**的哈希计算逻辑做了关键修改:

  • 在3.7及更早版本中,绑定方法的哈希值由「底层函数对象的哈希」与「实例对象的哈希」异或得到(即hash(method) = hash(method.__func__) ^ hash(method.__self__))。你的代码中A类重写了__hash__返回固定值12345,不同实例的同名方法会因为hash(method.__self__)相同,最终异或结果一致。
  • 从3.8开始,绑定方法不再使用自定义哈希逻辑,转而采用默认的object.__hash__实现——基于对象的内存地址(id)计算哈希。每个绑定方法都是独立的对象实例,因此不同实例的同名方法哈希值必然不同。

内容的提问来源于stack exchange,提问作者meow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:40:20