Skip to main content

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 another Struct object from it. This handles nested dictionaries of any depth.
  • setattr(self, key, Struct(**value)): If the value is a dictionary, this line recursively calls Struct. The double-asterisk ** is a dictionary unpacking
  • setattr(self, key, value): This sets an attribute on the current object (self). The attribute's name is key (the dictionary key), and its value is value. Using setattr is more appropriate than directly accessing self.__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 of Struct, 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}")