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

哈希值相同时仍抛出KeyError的问题排查

为何相同哈希值的可哈希对象作为字典键却抛出KeyError?

根据你提供的代码和运行结果,虽然目标对象与字典中的键地址相同、哈希值一致,但in判断返回False并抛出KeyError,核心原因在于字典查找依赖哈希值定位桶,再通过__eq__方法匹配键,二者任一环节出问题都会导致查找失败。具体可能的原因及解决方案如下:

可能的原因

1. 自定义属性的__eq__方法实现错误

你的TransactionDesignation类的__eq__方法依赖id、child_of、gd三个属性的相等性判断。如果这三个属性中任意一个是自定义类型,且其__eq__方法实现错误(比如错误地返回False,或未正确比较实例属性),会导致即使是同一个TransactionDesignation实例,__eq__也会返回False,字典无法匹配到键。

比如,假设id是一个自定义ORM模型实例,其__eq__方法错误地比较数据库主键(而该实例尚未入库,主键为None),就会出现同一个实例的id == id返回False的情况。

2. 对象属性被修改后恢复,导致字典内部结构异常

Python字典在插入键时会缓存键的哈希值。如果将对象加入字典后,修改了影响哈希值的属性(id/child_of/gd),即使之后改回原属性,字典的内部结构可能已无法正确关联当前对象与原存储位置,极端情况下会导致查找失败。

3. 未处理非同类实例的比较

你的__eq__方法未先判断other是否为TransactionDesignation实例,如果字典中存在其他类型的键,或查找时意外传入非同类对象,可能会触发错误的比较逻辑(甚至抛出异常),导致查找失败。

解决方案

1. 修复属性的相等性判断逻辑

检查id、child_of、gd的类型及其__eq__实现:

  • 对于自定义类型,确保其__eq__方法正确比较实例的核心属性;
  • 如果不需要自定义相等性判断,可直接使用默认的is判断(即比较对象地址),但需注意这会改变相等性逻辑。

2. 确保字典键的不可变性

一旦将TransactionDesignation实例作为字典键,就不要修改其id、child_of、gd属性。如果必须修改,需先从字典中删除该键,修改后重新添加:

# 修改属性前先删除键
del logs[TRANSACTIONS][transaction_designation]
# 修改属性
transaction_designation.id = new_id
# 重新添加到字典
logs[TRANSACTIONS][transaction_designation] = transaction_value

3. 完善__eq__方法的类型判断

在__eq__方法中先判断other的类型,避免与非同类对象错误比较:

def __eq__(self, other):
    if not isinstance(other, TransactionDesignation):
        return False
    return self.id == other.id and self.child_of == other.child_of and self.gd == other.gd

4. 快速排查测试

添加以下测试代码,定位问题根源:

# 测试同一个实例的__eq__结果
td = TransactionDesignation(gd, id, child_of)
print(td == td)  # 若返回False,说明__eq__方法存在问题

# 测试属性的相等性
print(td.id == td.id)
print(td.child_of == td.child_of)
print(td.gd == td.gd)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 08:56:05