How to make immutable dictionaries in Python #PyTip01

How to make immutable dictionaries in Python #PyTip01

Python is known for its batteries included capability, it has solutions for every data structure requirements. Dictionaries in Python are very useful when storing a record as Key/Value pairs. Although dictionaries are awesome, they are mutable that means their values can be changed after their intialization.

In this short post you will learn how you can use MappingProxyType to make your dictionaries immutable.

Problem

Below is the example of how you would use dictionaries in Python.

>>> person = {"id" : 735616, "first_name": "John", "last_name":"Doe"}
>>> person["id"]
735616
>>> person["first_name"] + ' ' + person["last_name"]
'John Doe'
>>> person["id"] = 000000
>>> person["id"]
0

In the above code we can see that our person record was changed and we have no way to block this change. This is where MappingProxyType comes in.

Solution

MappingProxyType is a read-only wrapper that provides a proxy to the underlying data structure. MappingProxyType do not support item assignment which makes our data immutable.

>>> from types import MappingProxyType
>>> im_person = MappingProxyType({"id":736533, "first_name":"John", "last_name":"Doe"})
>>> im_person["id"]
736533
>>> im_person["id"] = 87
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'mappingproxy' object does not support item assignment

In the above example you can see that when we attempted to change the value of id, MappingProxyType immediately throws TypeError, thus making our dictionary immutable. Please note that MappingProxyType accepts any data type not just dictionaries. You can also use str and list.

Caveat

Before using MappingProxyType, you must know that it only provides a Proxy to the underlying data structure which means if the underlying data is changed then MappingProxyType will reflect those changes.

>>> im_person = MappingProxyType(person)
>>> im_person
mappingproxy({'id': 0, 'first_name': 'John', 'last_name': 'Doe'})
>>> person
{'id': 0, 'first_name': 'John', 'last_name': 'Doe'}
>>> person["id"] = 00
>>> im_person
mappingproxy({'id': 0, 'first_name': 'John', 'last_name': 'Doe'})
>>>

As you can see in the above code that the MappingProxyType changed when the underlying data dictionary was changed.

Conclusion

In this short article you learned about types.MappingProxyType, they are useful when you want to make sure that your Key/Value pairs remains immutable. Hope you liked it.