Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write-once dictionary?

Tags:

python

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.

like image 987
xorsyst Avatar asked Dec 16 '22 01:12

xorsyst


1 Answers

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

like image 82
Martijn Pieters Avatar answered Jan 08 '23 23:01

Martijn Pieters