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

Python的dict将类型作为键时__hash__与__eq__的运作机制是怎样的?

核心原理解答

首先你要明确一个Python的基础规则:所有自定义类本身,就是type类的实例。你遇到的疑惑本质是混淆了「类给自身实例提供的方法」和「类作为其他类的实例时调用的方法」。

测试代码报错的原因

你写Apple.__hash__()的时候,调用的是Apple类继承自object、给Apple的实例(比如an_apple)用的__hash__方法,这个方法要求第一个参数必须是Apple的实例,你不传当然会报错。但这根本不是字典把Apple作为键时会调用的方法。

dict处理键的统一逻辑

不管键是什么对象,dict计算哈希和做相等校验的逻辑都是固定的:

  • 计算哈希时,执行hash(键对象),本质等价于调用type(键对象).__hash__(键对象)
  • 相等校验时,执行键对象1 == 键对象2,本质等价于调用type(键对象1).__eq__(键对象1, 键对象2)

当你把Apple类作为键时:

  • 键对象就是Apple,它的类型是type,所以实际调用的是type.__hash__(Apple)
  • 相等校验时调用的是type.__eq__(Apple, 待比较的对象)

type类本身已经实现了符合要求的__hash__和__eq__方法,所有类作为type的实例天然是可哈希的,完全满足dict键的要求,所以可以正常作为键使用。

验证示例

你可以执行以下代码验证上述逻辑:

# 不会报错,正常返回Apple类的哈希值
print(hash(Apple))
# 输出True,相等校验正常
print(Apple == type(an_apple))

这就是你的lookup字典可以正常工作的原因:type(an_apple)得到的就是Apple类对象,和字典里存的键哈希值一致、相等判断为真,自然可以取出对应的lambda执行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 10:12:01