简体   繁体   English

具有固定和有序键的可变字典

[英]Mutable dictionary with fixed and ordered keys

I am using OrderedDict for storage of some important data. 我使用OrderedDict存储一些重要数据。 I want to ensure, that accidentally inserted new key to this dictionary throws an exception but I want dict to be mutable . 我想确保,意外插入此字典的新密钥会引发异常,但我希望dict是可变的 I want keys to be fixed (after created in __init__ ). 我希望修复键(在__init__创建之后)。 Is it possible to do that with some library class? 是否可以使用某些库类? Or do I have to somehow implement new ordered class for this? 或者我是否必须以某种方式为此实现新的有序类?

Example: 例:

d = FixedOrderedDict( ( ("A", 1), ("B", 2) ) )

print d["A"]
# 1
d["A"] = 11
print d["A"]
# 11
d["C"] = 33
# throws exception

I was recommended to look up solution called FrozenDict but it makes dict read-only - values cannot be modified (throws exception when assigning new values). 我被建议查找名为FrozenDict的解决方案,但它使dict只读 - 值无法修改(在分配新值时抛出异常)。 This is not what I want to achieve. 这不是我想要达到的目标。

I'm not aware of such a solution in the standard library (it's a rather specialized use case). 我不知道标准库中的这种解决方案(这是一个相当专业的用例)。 You can however use collections.MutableMapping ( collections.abc.MutableMapping in 3.3 and onwards) to get most functionality for free. 但是,您可以使用collections.MutableMapping (3.3及更高版本中的collections.abc.MutableMapping )来免费获得大多数功能。 Give or take a few minor issues I may be overlooking right now, it's just: 给出或采取我现在可能忽略的一些小问题,它只是:

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)

You need a subclass of dict that allows you to freeze the keys at some point but allow the values to mutate? 你需要一个dict的子类,它允许你在某些时候冻结键但允许值变异? This one lets you freeze keys after filling, to allow more flexibility. 这个允许您在填充后冻结密钥,以提供更大的灵活性。

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"

Be careful, though, to remember that not all methods are wrapped here and it does not attempt to be a complete emulation of OrderedDict - the code assumes all inherited methods will operate correctly. 但要小心,要记住并非所有方法都包含在此处,并且它不会尝试完全模拟OrderedDict - 代码假定所有继承的方法都能正常运行。 For example, item deletion is currently still permitted even after freezing. 例如,即使冻结后,目前仍允许删除项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM