Search code examples
pythonlistdictionarygetter-setter

Auto-perform actions when updating a mutable in Python


I know how to use property setters to perform actions every time an attribute of a class is modified to avoid having to code in every action every time the variable is changed.

I wanted to know if it was possible to do the same for mutables, like lists and dictionaries ?

What I want to achieve is the following,

I have a dictionary d = {string : object}

with object an instance of a class which has an attribute called x.

when I add a new string:object pair to my dictionary, and that the attribute x of the object is != 0, then I also add the object to a list called x_instances.


Solution

  • You'd have to use a custom class; you could subclass dict or collections.UserDict(), and override the appropriate container special methods to detect changes.

    For example, object[subscription] = value is translated to object.__setitem__(subscription, value), letting you inspect value and act on that:

    class MutationDictionary(dict):
        def __setitem__(self, key, value):
            super().__setitem__(key, value)
            if isinstance(value, SomeClass) and value.x != 0:
                x_instances.append(value)
    

    Do look over the other methods that dict objects implement; you may want to override dict.setdefault() too for example.