14

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

在最近的一个问题中,我询问了有关在 Python 中散列不可变字典的问题。从那时起,我构建了一个不可变的、可散列的字典,我对此很满意。然而,我意识到它有一个漏洞:由,返回的字典视图,仍然允许自己意外地改变我的(假定的)不可变字典。keys()items()values()

Stack Overflow 上我能找到的关于字典视图的唯一问题是Python 创建自己的字典子集的字典视图,但这似乎与我的问题没有太大关系,以及“冻结字典”的答案是什么? 似乎没有进入压倒一切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 不能修改 dicts。在Python 3 文档中,我误读了“它们提供了字典条目的动态视图,这意味着当字典更改时,视图会反映这些更改”,就像“当视图更改时,字典会反映这些更改”一样。显然这不是文档所说的。

4

2 回答 2

6

在 Python 2.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
于 2012-04-11T18:03:11.493 回答
0

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

你的观点如何改变你的字典?视图不支持项目分配或删除,所以我不相信它们可以改变底层字典。

于 2012-04-11T18:01:27.093 回答