Write-once dictionary?

python

Solution

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().__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.abc.MutableMapping()` as it implements most methods for you in terms of `__getitem__`, `__setitem__` and `__delitem__` calls:

from collections.abc import MutableMapping

class StrictWriteOnceDict(MutableMapping, dict):
    # dict implementations to override the MutableMapping versions
    __getitem__ = dict.__getitem__
    __iter__ = dict.__iter__
    __len__ = dict.__len__

    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__`.

Problem

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.

Original source