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

Python如何将对象引用作为字典key且无需自定义__hash__和__eq__方法

问题解答

Python 支持直接将自定义类实例的引用作为字典的 key,且默认行为就可以满足你的需求,不需要自定义 __hash__ 和 __eq__ 方法。

核心原理

用户自定义类的实例默认自带的 __hash__ 和 __eq__ 方法基于对象的唯一内存身份(即 id() 函数的返回值)实现:

  • 哈希值计算只和对象的内存地址绑定,和实例内部的属性无关
  • 相等判断默认等价于 is 运算符,仅当两个变量指向同一个内存地址的对象时才返回 True

这种情况下,无论你修改实例的任意属性,只要实例本身还是同一个内存地址的对象,作为字典 key 的身份就不会发生变化,完全可以正常索引到对应的值。

示例代码

你只需要删除你代码中自定义的 __hash__ 和 __eq__ 方法即可正常运行:

class Example:
  def __init__(self, id):
    self.id = id

# 创建实例
obj = Example("My object")
# 直接作为字典key
instances = {obj: 1}
# 修改实例属性
obj.id = "Not my object"
# 依然可以正常获取对应值
print(instances[obj]) # 输出 1

原代码问题原因

你当前遇到修改属性后字典找不到 key 的问题,正是因为你主动重写了 __hash__ 和 __eq__ 方法,把哈希和相等判断的逻辑绑定到了可变的 id 属性上。这违反了字典对 key 的核心要求:对象作为字典 key 存在的生命周期内,其哈希值必须保持不变。当你修改 id 属性后,实例的哈希值发生了变化,自然无法匹配到字典中原来的存储槽位。

可选替代方案

如果你后续需要同时支持「按属性判断实例相等」和「按实例引用作为 key」的需求,也可以不修改类定义,直接用实例的内存 id 作为字典的 key:

obj = Example("My object")
instances = {id(obj): 1}
obj.id = "Not my object"
print(instances[id(obj)]) # 输出 1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:57:06