我遇到的问题分布在许多源文件中,我试图以简单的线性格式重现该问题的尝试失败了。尽管如此,我遇到的问题还是简单地描述了一下
我有一个类Path
,我为它实现了__hash__
和__eq__
我在dict
中有一个类型为Path
的项,如
path in list(thedict)
>> True
我验证path == other
和hash(path) == hash(other)
和id(path) == id(other)
,其中other
是直接从^{
path in thedict:
>> False
并在KeyError
中尝试以下结果
thedict[path]
所以我的问题是,在什么情况下这是可能的?我本以为如果path
在list(thedict)
中,那么它一定在thedict.keys()
中,因此我们必须能够写thedict[path]
。这个假设有什么错
如果有帮助,下面列出了相关的课程。正是在{
class Path:
pass
@dataclass
class ConfigurationPath(Path):
configurationName: str = None
def __repr__(self) -> str:
return self.configurationName
def __hash__(self):
return hash(self.configurationName)
def __eq__(self, other):
if not isinstance(other, ConfigurationPath):
return False
return self.configurationName == other.configurationName
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@dataclass
class SpecificationPath(Path):
configurationPath: ConfigurationPath
specificationName: str = None
def __repr__(self) -> str:
return f"{self.configurationPath}.{self.specificationName or ''}"
def __hash__(self):
return hash((self.configurationPath, self.specificationName))
def __eq__(self, other):
if not isinstance(other, SpecificationPath):
return False
if self.configurationPath != other.configurationPath:
return False
if self.specificationName != other.specificationName:
return False
return True
下面是(Spyder)调试终端中的输出,其中pf
是一个包含使用路径作为键的paths
字典的对象,该对象(self
)具有路径
In : others = list(pf.paths.keys())
In : other = others[1]
In : self.path is other
Out[1]: True
In : self.path in pf.paths
Out[1]: False
每your comment:
这是你的问题。您在创建之后立即将这些对象放入
dict
中,而specificationName
是None
,因此它使用基于None
的哈希代码存储在dict
中(该哈希代码缓存在dict
本身中,使用该哈希代码是将来查找对象的唯一方法)。如果随后将其更改为产生不同散列值的任何(读取几乎所有其他内容),则该对象存储在与旧散列代码相对应的bucket中,但使用它进行查找会计算新散列代码,并且找不到该bucket如果
specificationName
必须是可变的,那么它不能是散列的一部分,就这么简单。这可能会增加碰撞,但也没办法;一个可变字段不能成为散列的一部分而不触发这个确切的问题相关问题 更多 >
编程相关推荐