pythonpython-3.9

Python dictionary with fixed .keys() contents and variable arguments


I'm trying to read in a bunch of data from text files to a dictionary, and I've made a couple of small typos which end up creating new key/value pairs and breaking the program (which can be annoying and a pain to debug).

This got me wondering if there is a way to create a dictionary to which no keys can be added or removed after the initial declaration. This strikes me as something that must exist but I can't find an example of it; does anyone know of something that would fit the bill?

def change_key(dictionary, key, new_value):
    a = dictionary.__len__()
    dictionary[key] = new_value
    if dictionary.__len__() != a:
        raise ValueError("new key added")

What I'm looking for is a more elegant implementation of the code above that is:

  1. not a massive mess of code

  2. capable of dealing with things like appending to a nested list or adding to a nested dict

  3. reasonably efficient


Solution

  • I believe what you're looking for is a dataclass with__slots__ method (In Python 3.10+, this can be achieved with @dataclass(slots=True)). In addition to fixing your keys, a slotted class also has an additional benefit of being both faster and more memory-efficient than an ordinary class:

    from dataclasses import dataclass, asdict
    
    
    @dataclass
    class FixedKeys:
        __slots__ = ("key_1", "key_2", "key_3")
        key_1: str
        key_2: str
        key_3: str
    
    
    d = FixedKeys(key_1="something", key_2="something_else", key_3="another_thing")
    d.key_1 = "updated_value"  # This will work fine
    d.key_that_was_not_predefined = "some value"  # This will raise an AttributeError
    d = asdict(d)  # This converts a dataclass instance to a normal dictionary