I'd quite like to have a write-once dictionary object in Python, so that:
my_dict[1] = 'foo'
my_dict[2] = 'bar'
my_dict[1] = 'baz'  # Raises KeyError
I can imagine making a straightforward one, but I wonder if a better-thought-out recipe exists? I couldn't find one.
It's easy enough to implement a subclass:
class WriteOnceDict(dict):
    def __setitem__(self, key, value):
        if key in self:
            raise KeyError('{} has already been set'.format(key))
        super(WriteOnceDict, self).__setitem__(key, value)
You could also provide a custom update() method, and depending on how strict you want to be, __delitem__(), pop(), popitem(), and clear() may need overriding too.
For the super-strict version, it's easier to mix in collections.MutableMapping() as it implements most methods for you in terms of __getitem__, __setitem__ and __delitem__ calls:
from collections import MutableMapping
class StrictWriteOnceDict(MutableMapping, dict):
    # dict implementations to override the MutableMapping versions
    __getitem__ = dict.__getitem__
    __iter__ = dict.__iter__
    def __delitem__(self, key):
        raise KeyError('Read-only dictionary')
    def __setitem__(self, key, value):
        if key in self:
            raise KeyError('{} has already been set'.format(key))
        dict.__setitem__(self, key, value)
Allowing deletion is as simple as replacing the __delitem__ method with __delitem__ = dict.__delitem__.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With