Python字典含对应值却触发KeyError问题排查与解决
问题原因
- Tile类未正确实现
__eq__与__hash__方法:Python字典判断键是否存在,依赖对象的哈希值与相等性逻辑。如果Tile类使用默认的__hash__(基于对象内存地址),哪怕两个Tile逻辑上是同一个空白瓦片,不同实例的哈希值也会不同,字典会将它们视为不同键。你看到的哈希值是规则集里那个Tile实例的内存哈希,而createBlank()返回的是新实例,哈希自然不匹配,触发KeyError。 createBlank()返回新实例而非规则集中的同一对象:如果TileFactory.createBlank()每次调用都创建新的Tile对象,即使属性和规则集中的空白Tile完全一致,默认情况下Python也不会认为它们是同一个字典键。
解决方法
- 为Tile类实现自定义的
__eq__和__hash__:根据Tile的核心标识属性(比如空白瓦片的类型标记)定义相等性与哈希逻辑,确保逻辑相同的Tile实例能被字典识别为同一键。示例代码:
class Tile: def __init__(self, tile_id): self.tile_id = tile_id # 用tile_id作为核心标识,比如空白瓦片的tile_id设为"blank" def __eq__(self, other): if not isinstance(other, Tile): return False return self.tile_id == other.tile_id def __hash__(self): return hash(self.tile_id)
- 让
createBlank()返回单例实例:确保每次调用createBlank()都返回同一个Tile对象,而非新创建实例,保证和规则集中的空白Tile是同一对象。示例代码:
class TileFactory: _singleton_blank = None @classmethod def createBlank(cls): if cls._singleton_blank is None: cls._singleton_blank = Tile("blank") return cls._singleton_blank
- 调试验证键匹配情况:在报错前添加调试代码,确认两个Tile的哈希值与相等性:
blank_tile = TileFactory.createBlank() rule_dict = TileRuleSetFactory.createAll() # 找到规则集中的空白Tile rule_blank = next(t for t in rule_dict.keys() if t.tile_id == "blank") print(f"规则集空白Tile哈希: {hash(rule_blank)}") print(f"createBlank()返回Tile哈希: {hash(blank_tile)}") print(f"是否相等: {blank_tile == rule_blank}")
通过输出能快速定位是哈希/相等性问题,还是实例不统一的问题。
内容的提问来源于stack exchange,提问作者Avinash Devineni
相关产品推荐
相关产品推荐

