Python:创建后冻结dict键

Python:创建后冻结dict键,python,dictionary,immutability,keyvaluepair,Python,Dictionary,Immutability,Keyvaluepair,有没有可能在创建python dict之后“冻结”它,这样就不可能向它添加新的键?只能更改现有的键值 如果没有,您如何知道何时更改现有的键值对以及何时添加新的键值对?可能是这样的: class FreezableDict (dict): __frozen = False def freeze (self): self.__frozen = True def __setitem__ (self, key, value): if self.

有没有可能在创建python dict之后“冻结”它,这样就不可能向它添加新的键?只能更改现有的键值


如果没有,您如何知道何时更改现有的键值对以及何时添加新的键值对?

可能是这样的:

class FreezableDict (dict):
    __frozen = False

    def freeze (self):
        self.__frozen = True

    def __setitem__ (self, key, value):
        if self.__frozen and key not in self:
            raise ValueError('Dictionary is frozen')
        super().__setitem__(key, value)
或者仅仅在一行中,没有参考原始词典:

>>> x = types.MappingProxyType({'foo': 'bar', 'baz': 'bla'})
>>> x
mappingproxy({'baz': 'bla', 'foo': 'bar'})
>>> x['hello'] = 'world'
Traceback (most recent call last):
  File "<pyshell#60>", line 1, in <module>
    x['hello'] = 'world'
TypeError: 'mappingproxy' object does not support item assignment
>x=types.MappingProxyType({'foo':'bar','baz':'bla'})
>>>x
映射代理({'baz':'bla','foo':'bar'})
>>>x['hello']='world'
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
x['hello']='world'
TypeError:“mappingproxy”对象不支持项分配

这在“普通”dict中是不可能的。您可能需要对
集合进行子类化。可变映射

未经测试的代码如下


您可以使用
if(输入dict)检查字典中是否有值:…
所以您只想冻结键,而不是冻结字典中的所有键,对吗?@jornsharpe--我不确定是否同意此结束。OP说“冻结”,但并不是真正的意思,因为他/她真的只是想指定可以操纵的键,不允许任何其他键。相关:我不认为这是完全重复的,因为你只想冻结钥匙。顺便说一句,在标准图书馆里没有这样的东西。为了知道字典中是否有密钥,请使用@iwin suggestion:
print'ready In'if key In dict else'not here'
这个主意很酷,但我不喜欢类名
FrozenDict
,这对我来说意味着一个不可变的、可哈希的dict。@wim我愿意接受建议;)+1但是为了赢得比赛,也许
类FreezableDict
喜欢使用
类型。MappingProxyType
-绝对+1 2.7版有没有对应的MappingProxyType?你的
超级版和类名似乎不一致:)@JonClements--D'oh!当您无法决定如何命名事物,并且没有使用python3.x作为示例时,就会发生这种情况;-)我也可能会将
self.\u dict.keys()
更改为
list(self.\u dict)
,因此它与well@JonClements--我在这个问题上反复讨论--人们通常希望
列表(self.\u dict)
列出
项,而不仅仅是键。也许是
list(self)
来强迫大家想一想?嗯,
list(self)
将是空的,因为所有数据都在
self中。dict
不是
集合。可变映射是对象的一部分(选择一个或另一个)
>>> x = {'foo': 'bar'}
>>> y = types.MappingProxyType(x)
>>> y
mappingproxy({'foo': 'bar'})
>>> x['baz'] = 'bla'
>>> y
mappingproxy({'baz': 'bla', 'foo': 'bar'})
>>> y['hello'] = 'world'
Traceback (most recent call last):
  File "<pyshell#55>", line 1, in <module>
    y['hello'] = 'world'
TypeError: 'mappingproxy' object does not support item assignment
>>> del x
>>> y
mappingproxy({'baz': 'bla', 'foo': 'bar'})
>>> x = types.MappingProxyType({'foo': 'bar', 'baz': 'bla'})
>>> x
mappingproxy({'baz': 'bla', 'foo': 'bar'})
>>> x['hello'] = 'world'
Traceback (most recent call last):
  File "<pyshell#60>", line 1, in <module>
    x['hello'] = 'world'
TypeError: 'mappingproxy' object does not support item assignment
class FrozenKeyDict(collections.MutableMapping):
    """Mapping which doesn't allow keys to be added/deleted.

    It does allow existing key/value pairs to be modified.
    """
    def __init__(self, *args, **kwargs):
        self._frozen = False
        self._dict = {}
        super(FrozenKeyDict, self).__init__(*args, **kwargs)
        self._frozen = True

    def __getitem__(self, key):
        return self._dict[key]

    def __setitem__(self, key, value):
        if self._frozen and key not in self._dict:
            raise KeyError('must be one of %s' % list(self))
        self._dict[key] = value

    def __delitem__(self, key):
        # modify to suit your needs ...
        raise KeyError('Removing keys not supported')

    def __iter__(self):
        return iter(self._dict)

    def __len__(self):
        return len(self._dict)