Python: Read Only Dictionaries

Akshay Chavan
2 min readApr 19, 2023
Open dictionary to read
Photo by Pisit Heng on Unsplash

Everything in a Python object is a pretty much accessible and is passed by reference. Even the methods with __*__can be modified, though by convention they are supposed to be private.

So what if you really don’t want a user to modify a dict in your object, is it possible? Well yes and no, because everything is accessible in python a certain user might be able to modify the data by peeking under the hood.
However, if you want to avoid accidental overwrite of data then there are a few ways, which we will discuss here.

When you modify a key value pair in the dictionary, __setitem__(link) is invoked. So suppressing it will stop the user from modifying the dictionary.

Here is an example on how to do suppress assignment operation:

Now this will prevent the user from modifying the dictionary.
However, what if you want you to be able to modify the dictionary but pass it as a read only dictionary to a function. In other words, we are trying to replicate the const(link) attribute in C++.

This can be accomplished by making a copy of the dictionary and then passing it to the function. This way, even if the method modifies the given dictionary, it won’t modify the original copy of the object.

That's all great. However, what if you want to be able to modify the original dictionary outside a method that should not modify the original dictionary. In a very rare scenario, where we want to retain the ability to modify the dict object outside a read-only method, it has being made possible with the MappingProxyTypedata type.

The MappingProxyType in the typespackage not only makes a dictionary read-only or immutable, but also reflects the changes done to the original dictionary after it has been cast as a MappingProxyType.

Here is a bit more complex example, where the object that is passed to another thread as a read only object and changes made to the object in the main thread reflect in the thread with the read only version of the object. Modifying the MappingProxyTypewill result in a TypeErrorsaying 'mappingproxy’ object does not support item assignment.

Output:

Main    : {'key': 'original'}
Main : before creating thread
Main : before running thread
Thread 1: startingMain : wait for 2 seconds

Thread 1: {'key': 'original'}
Thread 1: wait for 5 seconds
Main : {'key': 'modified'}
Main : wait for the thread to finish
Main : all done
Thread 1: {'key': 'modified'}
Thread 1: finishing

Without going into too much depth, a MappingProxyType is simply a dict with no __setattr__method.

If you have come across any interesting application for MappingProxyType, do post then in the comments section.

--

--