我使用OrderedDict存储一些重要数据。我想确保,意外插入此词典的新密钥会引发异常,但我希望dict为 mutable 。我希望修复密钥(在__init__
中创建后)。是否可以使用某些库类?或者我是否必须以某种方式为此实现新的有序类?
示例:
d = FixedOrderedDict( ( ("A", 1), ("B", 2) ) )
print d["A"]
# 1
d["A"] = 11
print d["A"]
# 11
d["C"] = 33
# throws exception
我被建议查找名为 FrozenDict 的解决方案,但它使dict为只读 - 无法修改值(在分配新值时抛出异常)。这不是我想要实现的目标。
答案 0 :(得分:4)
我不知道标准库中的这种解决方案(它是一个相当专业的用例)。但是,您可以使用collections.MutableMapping
(3.3及之后的collections.abc.MutableMapping
)免费获得大多数功能。给出或采取我现在可能忽略的一些小问题,它只是:
from collections import MutableMapping, OrderedDict
class FixedOrderedDict(MutableMapping):
def __init__(self, *args):
self._d = OrderedDict(*args)
def __getitem__(self, key):
return self._d[key]
def __setitem__(self, key, value):
if key not in self._d:
raise KeyError("Must not add new keys")
self._d[key] = value
def __delitem__(self, key):
raise NotImplementedError("Must not remove keys")
def __iter__(self):
return iter(self._d)
def __len__(self):
return len(self._d)
答案 1 :(得分:1)
你需要一个dict
的子类,它允许你在某些时候冻结键但允许值变异?这个允许你在填充后冻结键,以提供更大的灵活性。
from collections import OrderedDict
class FreezableDict(OrderedDict):
def __init__(self, *args, **kw):
super(OrderedDict, self).__init__(*args, **kw)
self._frozen = False
def __setitem__(self, key, value):
if key not in self and self._frozen:
raise TypeError("No key additions once a FreezableDict is frozen!")
return super(OrderedDict, self).__setitem__(key, value)
def freeze(self):
self._frozen = True
d = FreezableDict((("A", 1), ("B", 2)))
print d["A"]
d["C"] = "New Value"
d.freeze()
d["C"] = "Replacement"
print d["C"]
d["D"] = "This raises a TypeError exception"
但是要小心,要记住并非所有方法都包含在此处,并且它不会尝试完全模拟OrderedDict
- 代码假定所有继承的方法都能正常运行。例如,即使冻结后,目前仍允许删除项目。