如何让dataclass与字符串哈希值相同,实现字典键跨类型查找?
问题出在哪?
字典找键不是只看哈希值,得满足两个条件:
- 哈希值相同,这样才会被分到同一个哈希桶里
- 两个对象用
==比较结果为True,这才会被认定是同一个键
你只重写了__hash__让Key实例和字符串的哈希值一样,但默认的dataclass__eq__只会把同类型的实例拿来比——Key(name="foo")和字符串"foo"类型不一样,所以==结果是False,字典自然找不到对应的键。
怎么改?
重写__eq__方法,让Key实例能和字符串直接比较:
from dataclasses import dataclass @dataclass(eq=True, frozen=True) class Key: name: str def __hash__(self): return hash(self.name) def __eq__(self, other): # 对方是字符串的话,直接比name字段 if isinstance(other, str): return self.name == other # 是Key实例就按默认逻辑比 return super().__eq__(other) k = "foo" foo = Key(name=k) d = {} d[foo] = 1 print(d[k]) # 输出1 print(hash(k) == hash(foo)) # 输出True
这么改之后,用字符串"foo"查字典时,会先通过哈希找到对应的桶,再通过__eq__判定Key("foo")和"foo"相等,就能拿到值了。
注意:如果你的字典里还会混其他类型的键,这种比较逻辑可能出问题,所以只建议在确定只有Key实例和字符串作为键的场景下用。
内容的提问来源于stack exchange,提问作者Tom McLean
相关产品推荐
相关产品推荐

