Python 3中的不可变字典:如何使keys()、items()和values()字典视图不可变

2024-05-20 05:27:39 发布

您现在位置:Python中文网/ 问答频道 /正文

简短版本:什么是覆盖dict.keys()和朋友的最佳方法,以防止自己在Python 3中意外修改(应该是)不可变的字典?

在最近的一个问题中,我问了关于Hashing an immutable dictionary in Python。从那时起,我已经建立了一个不可变的,散列字典我很高兴。然而,我意识到它有一个漏洞:由keys()items()values()返回的dictionary views仍然允许我自己意外地对我的(假定的)不可变字典进行变异。

我能找到的关于字典视图的堆栈溢出的唯一问题是Python create own dict view of subset of dictionary,但这似乎与我的问题没有太大关系,而且What would a "frozen dict" be?的答案似乎没有涉及重写keys()

这样做会不会防止我不小心修改,例如,不可变字典的键?

class FrozenCounter(collections.Counter):
    "Model an hashable multiset as an immutable dictionary."
    # ...
    def keys(self):
        return list(super().keys())
    def values(self):
        return list(super().values())
    def items(self):
        return list(super().items())


我从答案中得到的

我主要不会读书。

dictviews无法修改dict。在Python 3 documentation中,我误读了“它们提供了字典条目的动态视图,这意味着当字典发生变化时,视图反映这些变化”的意思是“当视图发生变化时,字典反映这些变化”。显然文档并不是这么说的。


Tags: ofselfan视图dictionaryreturn字典def
2条回答

这可能是个坏主意,因为它打破了那些方法首先返回视图的假设,并用不再更新以匹配底层dict的可变对象替换它们

你的观点如何改变你的字典?视图不支持项分配或删除,因此我不相信它们可以更改基础字典。

在Python2.x中,视图不允许改变底层对象:

>>> a = { 'a' : 1 }
>>> a.keys()[0] = 'b'
>>> a
{'a': 1}
>>> a.values()[0] = 'b'
>>> a
{'a': 1}

在Python 3.x中,改变视图会产生一个TypeError:

>>> a = { 'a':1}
>>> a.keys()[0] = 'b'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'dict_keys' object does not support item assignment

相关问题 更多 >