How to Convert Nested Dictionaries to Objects in Python
This guide explains how to convert nested dictionaries in Python into objects, allowing you to access dictionary values using the more readable dot notation (e.g., obj.attribute
) instead of bracket notation (e.g., obj['attribute']
). We'll create a custom Struct
class to achieve this conversion recursively.
Creating the Struct
Class
The core of this conversion is a custom class (we'll call it Struct
) that recursively transforms dictionary key-value pairs into object attributes:
class Struct:
def __init__(self, **kwargs):
for key, value in kwargs.items():
if isinstance(value, dict):
# Recursively convert nested dictionaries to Struct objects
setattr(self, key, Struct(**value))
else:
setattr(self, key, value) # set attribute
__init__(self, **kwargs)
: The constructor uses**kwargs
to accept arbitrary keyword arguments. This allows us to pass a dictionary directly to the constructor.for key, value in kwargs.items():
: We iterate through the key-value pairs of the input dictionary.if isinstance(value, dict):
: This is the crucial recursive step. If a value is itself a dictionary, we recursively create anotherStruct
object from it. This handles nested dictionaries of any depth.setattr(self, key, Struct(**value))
: If the value is a dictionary, this line recursively callsStruct
. The double-asterisk**
is a dictionary unpackingsetattr(self, key, value)
: This sets an attribute on the current object (self
). The attribute's name iskey
(the dictionary key), and its value isvalue
. Using setattr is more appropriate than directly accessingself.__dict__
.
Using the Struct
Class
Now, let's see how to use the Struct
class:
my_dict = {
'name': 'tutorialreference',
'address': {
'country': 'Country A',
'city': 'City A',
'codes': [1, 2, 3] # Lists are handled correctly
},
}
obj = Struct(**my_dict)
# Access attributes using dot notation:
print(obj.address.country) # Output: Country A
print(obj.address.codes) # Output: [1, 2, 3]
print(obj.name) # Output: tutorialreference
obj = Struct(**my_dict)
: We create an instance ofStruct
, passing our dictionary. The double-asterisk**
unpacks the dictionary into keyword arguments.- You can access the elements using the dot
.
notation.
Adding new attributes
New attributes can be added using the dot notation:
obj.address.greet = 'hello world'
print(obj.address.greet) # Output: hello world
Accessing Non-Existing Attributes
If you try to access an attribute that does not exist on an object, Python will raise an AttributeError
exception:
try:
print(obj.missing) # Access a non-existent attribute
except AttributeError as e:
print(f"Error: {e}")