How to Convert Dictionary to Datacalss in Python

Salman Mehmood Feb 15, 2024
  1. Convert a Dictionary Back Into a Data Class
  2. Convert a Dictionary Back Into a Data Class With __post_init__
  3. Convert a Dictionary Back Into a Data Class With Custom Implementation
  4. Convert a Dictionary Back Into a Data Class With dacite (Third Party Library)
  5. Convert a Dictionary Back Into a Data Class With Direct Assignment
  6. Conclusion
How to Convert Dictionary to Datacalss in Python

In Python programming, there are instances where we encounter the need to convert a dictionary back into a data class. While this may not be a common task, it becomes essential to ensure seamless data handling and prevent unexpected behavior.

There are several methods and approaches to achieve this conversion, each catering to different needs and preferences. In this article, we’ll explore various techniques, including direct assignment, custom implementations, and leveraging third-party libraries like dacite, to efficiently convert dictionaries into data classes.

Convert a Dictionary Back Into a Data Class

Depending on the project you are working on, you may encounter a scenario where you need to convert a dictionary back into a data class. While it may be a rare case, there are certain situations where you might need to do the conversion, especially when you want to prevent unexpected behavior.

An example of such a scenario would be that the converted dictionary is nested or complex, like having members with complex types or members who are data classes.

from dataclasses import dataclass, asdict


@dataclass
class A:
    x: int


@dataclass
class B:
    x: A
    y: A


@dataclass
class C:
    a: B
    b: B

In the above case, the data class C can sometimes pose conversion problems when converted into a dictionary. The problems occur primarily due to the failed handling of types of class members.

To overcome this solution, you can choose several approaches based on your preference and the nature of the project. If you are working on a personal project with a good idea of the scope of the nature of the data, it is safe to use simple workarounds.

However, in the case of large-scaleable data, it is generally recommended to be safe and use third-party libraries (preferably open-source) since they are designed for operating on a large spectrum of use-cases. Thus, it allows them to handle a wider range of data variants.

Convert a Dictionary Back Into a Data Class With __post_init__

One common scenario is initializing instances of dataclasses from dictionaries. While the dataclasses module offers various methods for achieving this, one particularly useful approach is utilizing the __post_init__ method.

This method allows for additional initialization logic to be performed after the object has been created, making it ideal for setting default values from a dictionary.

from dataclasses import dataclass, field


@dataclass
class MyClass:
    field1: str
    field2: int = field(default=0)

    def __post_init__(self):
        if not hasattr(self, "field1") or self.field1 is None:
            self.field1 = "default_value"


data = {"field1": "custom_value"}
instance = MyClass(**data)

print(instance.field1)
print(instance.field2)

In the provided code, we define a MyClass dataclass with two fields: field1 and field2. The field2 attribute is set to have a default value of 0. Upon instantiation of a MyClass object with values provided in the data dictionary, field1 is assigned the corresponding value from the dictionary.

However, field2 is automatically assigned its default value of 0, as it is not provided in the dictionary. The __post_init__ method is utilized to check if field1 is missing or set to None, in which case it is assigned the default value default_value.

After the object is instantiated, the values of field1 and field2 are printed, confirming that field1 retains the provided value custom_value while field2 holds the default value of 0 as expected.

Output:

python dataclass from dict - output 1

Convert a Dictionary Back Into a Data Class With Custom Implementation

When initializing dataclass instances from dictionaries, custom implementation methods can provide additional flexibility and control over the initialization process. By combining custom implementation with the asdict() method, we can create a powerful solution for converting dictionaries to dataclass instances and vice versa.

Example:

import dataclasses as dc


def dict_to_dataclass(klass, d):
    try:
        fieldtypes = {f.name: f.type for f in dc.fields(klass)}
        return klass(**{f: dict_to_dataclass(fieldtypes[f], d[f]) for f in d})
    except:
        return d  # The object is not a dataclass field


@dc.dataclass
class SimpleDataClass:
    x: float
    y: float


@dc.dataclass
class ComplexDataClass:
    a: SimpleDataClass
    b: SimpleDataClass


line = ComplexDataClass(SimpleDataClass(1, 2), SimpleDataClass(3, 4))
assert line == dict_to_dataclass(ComplexDataClass, dc.asdict(line))
print("Success")

In this code example, we define a custom method dict_to_dataclass() that recursively converts a dictionary to a dataclass instance, similar to the previous example. We then create a SimpleDataClass instance and a ComplexDataClass instance containing nested SimpleDataClass instances.

We assert that the original instance is equal to the result of converting it back from a dictionary using the custom method with the asdict() function. The assertion passes successfully, indicating that the conversion was performed accurately.

Output:

python dataclass from dict - output 2

Convert a Dictionary Back Into a Data Class With dacite (Third Party Library)

dacite is an open-source, third-party library that aims to simplify the creation of data classes in Python. Luckily, the library consists of the function that does what we want: create a data class from a passed dictionary (nested or not).

The purpose of using the dacite method is to streamline the initialization of dataclass instances from dictionaries. This is particularly useful when working with external data sources, such as APIs or configuration files, where data is often provided in dictionary format.

Example:

from dataclasses import dataclass
from dacite import from_dict


@dataclass
class Point:
    x: float
    y: float


data = {"x": 3.5, "y": 7.2}
point = from_dict(Point, data)

print(point)

In this example, we define a simple dataclass Point representing a point in a two-dimensional space. We then create a dictionary data containing the coordinates (3.5, 7.2) of the point.

Using the from_dict() function from the dacite library, we initialize a Point instance point from the dictionary data. The printed output confirms that the initialization was successful, with the dataclass instance containing the expected attribute values.

Output:

python dataclass from dict - output 3

Convert a Dictionary Back Into a Data Class With Direct Assignment

This method involves directly assigning dictionary values to dataclass attributes, providing a straightforward and intuitive way to initialize dataclass instances from dictionary data. By directly assigning values, we can quickly and efficiently initialize dataclass instances without the need for additional method calls or loops, making the code concise and easy to understand.

Example:

from dataclasses import dataclass


@dataclass
class Point:
    x: float
    y: float


data = {"x": 3.5, "y": 7.2}

point = Point(**data)

print(point)

In this example, we define a simple dataclass Point representing a point in a two-dimensional space. We then create a dictionary data containing the coordinates (3.5, 7.2) of the point.

By directly assigning the dictionary values to the dataclass attributes using **data, we initialize a Point instance point. The printed output confirms that the initialization was successful, with the dataclass instance containing the expected attribute values.

Output:

python dataclass from dict - output 4

Conclusion

Converting dictionaries back into data classes in Python is a crucial task, especially when dealing with structured data or interacting with external data sources. Through techniques like direct assignment, custom implementations, and leveraging third-party libraries like dacite, we can streamline this process and ensure accurate conversion.

Each method offers its unique advantages and can be chosen based on the specific requirements of the project. By understanding and utilizing these techniques effectively, developers can enhance the robustness and flexibility of their Python applications when dealing with data conversion tasks.

Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

Related Article - Python Dictionary

Related Article - Python Dataclass