python字典中的键

python字典中的键,python,dictionary,hash,Python,Dictionary,Hash,我遇到的问题分布在许多源文件中,我试图以简单的线性格式重现该问题的尝试失败了。尽管如此,我遇到的问题还是简单地描述了一下 我有一个类路径,我为它实现了\uuuuu散列和\uuuuuuuuuu均衡 我在dict中有一个Path类型的项目 path in list(thedict) >> True 我验证path==other和hash(path)==hash(other)和id(path)==id(other)其中other是直接从列表(thedict.keys())中提取的项目。然

我遇到的问题分布在许多源文件中,我试图以简单的线性格式重现该问题的尝试失败了。尽管如此,我遇到的问题还是简单地描述了一下

我有一个类
路径
,我为它实现了
\uuuuu散列
\uuuuuuuuuu均衡

我在
dict
中有一个
Path
类型的项目

path in list(thedict)
>> True
我验证
path==other
hash(path)==hash(other)
id(path)==id(other)
其中
other
是直接从
列表(thedict.keys())中提取的项目。然而,我得到了以下信息

path in thedict:
>> False
并且尝试以下操作会导致
keyrerror

thedict[path]
所以我的问题是,在什么情况下这是可能的?如果
路径
列表(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
是一个对象,包含使用路径作为键的
路径
字典,并且该对象(
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
Per:


当我将
specificationName
设置为
None
时,路径确实希望是可变的(让它们匿名,待以后填写)。此外,在
specificationName
None
的情况下会发生这种情况,但是在我的简单测试脚本中,我可以将其设置为None而不会出错。散列实例的可变性会导致这样的错误吗

这是你的问题。创建后立即将这些对象放入
dict
中,而
specificationName
None
,因此它以
None
为基础存储在
dict
中(该哈希代码缓存在
dict
本身中,使用该哈希代码是将来查找对象的唯一方法)。如果随后将其更改为产生不同哈希值的任何内容(读取几乎所有其他内容),对象存储在与旧哈希代码对应的bucket中,但使用它进行查找会计算新哈希代码,并且找不到该bucket


如果
specificationName
必须是可变的,那么它就不能成为散列的一部分,就这么简单。这可能会增加冲突,但也没什么帮助;可变字段不能成为散列的一部分,而不会触发这个确切的问题。

路径可变吗?小挑剔:当
isinstance
检查失败时,你会将返回
NotImplemented
,而不是
False
;这将允许右侧类(如果它与左侧不相同)尝试比较(如果两者都返回
NotImplemented
,Python将其转换为
False
)@tdelaney不是真的,因为我在那本字典里有几个条目。这些不是类变量,因为我使用的是dataclass机制,它将它们转换成实例变量。注意:你手动实现
\uuuuueq\uuuuuuuuu
\uuuuuuuuuuu散列\uuuuu
有什么原因吗r不做任何更改;将其设置为
@dataclass(freezed=True)
也会为您生成
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
@dataclass(unsafe\uhash=True)
也会这样做,但会让您的实例可变,而散列实例不应该是可变的)。“路径-那么它们就不应该是可散列的。变异会破坏散列。另外,避免实现你自己的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但是,让
数据类
为您做这件事要好得多。虽然他们不建议这样做,但他们确实注意到,您甚至可以通过将属性定义初始化为
字段(hash=False)
(可能需要您使用
@dataclass(unsafe\u hash=True)来从生成的哈希中省略特定字段)
而不是
@dataclass(freezed=True)
来支持OP的可变字段的情况,该字段不应该是散列的一部分),这将允许
dataclass
生成
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu