How to detect if any element in a dictionary changes?

You could subclass dict and include some custom __setitem__ behavior:

class MyDict(dict):
    def __setitem__(self, item, value):
        print "You are changing the value of %s to %s!!"%(item, value)
        super(MyDict, self).__setitem__(item, value)

Example usage:

In [58]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:class MyDict(dict):
:    def __setitem__(self, item, value):
:        print "You are changing the value of %s to %s!!"%(item, value)
:        super(MyDict, self).__setitem__(item, value)
:--

In [59]: d = MyDict({"apple":10, "pear":20})

In [60]: d
Out[60]: {'apple': 10, 'pear': 20}

In [61]: d["pear"] = 15
You are changing the value of pear to 15!!

In [62]: d
Out[62]: {'apple': 10, 'pear': 15}

You would just change the print statement to involve whatever checking you need to perform when modifying.

If you are instead asking about how to check whether a particular variable name is modified, it’s a much trickier problem, especially if the modification doesn’t happen within the context of an object or a context manager that can specifically monitor it.

In that case, you could try to modify the dict that globals or locals points to (depending on the scope you want this to happen within) and switch it out for, e.g. an instance of something like MyDict above, except the __setitem__ you custom create could just check if the item that is being updated matches the variable name you want to check for. Then it would be like you have a background “watcher” that is keeping an eye out for changes to that variable name.

The is a very bad thing to do, though. For one, it would involve some severe mangling of locals and globals which is not usually very safe to do. But perhaps more importantly, this is much easier to achieve by creating some container class and creating the custom update / detection code there.

Leave a Comment