Converting Python Objects to Dict

Mateen Kiani

Mateen Kiani

Published on Sat Aug 02 2025·4 min read

converting-python-objects-to-dict

Introduction

Working with Python objects often means you need to turn them into dictionaries for serialization, debugging, or data transformation. Yet many developers overlook the simple mechanisms built into Python that can do this conversion cleanly and efficiently. How can you turn a custom class instance into a dict without endless boilerplate code?

You’ll discover several approaches—from the built-in __dict__ attribute to dataclasses.asdict, from the json module to third-party libraries like Pydantic. Understanding these methods helps you write cleaner code, improves maintainability, and prevents subtle bugs when serializing or inspecting your objects.

Using the dict Attribute

Every instance of a user-defined class stores its attributes in the special __dict__ attribute. You can access it directly:

class User:
def __init__(self, name, age):
self.name = name
self.age = age
user = User("Alice", 30)
user_dict = user.__dict__
print(user_dict) # {'name': 'Alice', 'age': 30}

This approach is quick, but note:

  • It only includes attributes in __dict__ (no @property or slots).
  • It exposes private attributes and those you might not want to serialize.

Tip: Clone the dict if you plan to modify it: user_dict.copy().

Converting Dataclasses with asdict

Python’s dataclasses module (Python 3.7+) streamlines object definitions. It also provides asdict() to convert dataclass instances into recursively built dictionaries:

from dataclasses import dataclass, asdict
@dataclass
class Point:
x: float
y: float
pt = Point(1.2, 3.4)
pt_dict = asdict(pt)
print(pt_dict) # {'x': 1.2, 'y': 3.4}

Benefits of dataclasses:

  • Automatic __init__, __repr__, __eq__ methods.
  • asdict() handles nested dataclasses.
  • Cleaner and more type-safe definitions.

Tip: Use field(default_factory=...) for mutable defaults.

Leveraging the json Module

Sometimes you need a quick hack: serialize to JSON, then parse back to dict. It’s not the fastest, but it works for simple objects with JSON-friendly attributes:

import json
class Book:
def __init__(self, title, authors):
self.title = title
self.authors = authors
book = Book("The Hobbit", ["Tolkien"])
json_str = json.dumps(book.__dict__)
book_dict = json.loads(json_str)
print(book_dict) # {'title': 'The Hobbit', 'authors': ['Tolkien']}

See more on serialization in the JSON stringify guide.

Writing a Custom to_dict Method

For full control, implement your own to_dict():

class Order:
def __init__(self, id, items, total):
self.id = id
self._items = items # protected
self.total = total
def to_dict(self):
return {
"order_id": self.id,
"items": [item.to_dict() for item in self._items],
"total": self.total
}

Advantages:

  • Exclude or rename fields.
  • Transform or validate values.
  • Handle nested objects precisely.

Tip: Keep to_dict logic simple to avoid hidden side effects.

Using Third-Party Libraries

When you need robust validation, nested schemas, or advanced features, libraries can help:

  • Pydantic: Data validation, parsing, and conversion. Use model.dict().
  • Marshmallow: Schema definitions, serialization, and deserialization.

Example with Pydantic:

from pydantic import BaseModel
class Product(BaseModel):
name: str
price: float
p = Product(name="Pen", price=1.5)
print(p.dict()) # {'name': 'Pen', 'price': 1.5}

Tip: Choose libraries based on project needs—avoid overkill for small scripts.

Handling Nested and Complex Objects

Nested objects require recursive conversion. Combine methods:

class Category:
def __init__(self, name):
self.name = name
class Item:
def __init__(self, title, category):
self.title = title
self.category = category
def to_dict(self):
return {
"title": self.title,
"category": self.category.__dict__
}
cat = Category("Books")
item = Item("1984", cat)
print(item.to_dict())
# {'title': '1984', 'category': {'name': 'Books'}}

For JSON round-trip parsing, see the JSON parser guide.

Performance Considerations

Benchmark before choosing a method:

MethodComplexityUse Case
__dict__O(n)Quick & simple
dataclasses.asdictO(n + nested)Typed structures
JSON round-tripO(n) + I/OQuick hack
Custom to_dictCustomFull control
  • For large datasets, avoid JSON round-trip.
  • Dataclasses are fast and lean for typed data.
  • Third-party libraries add overhead but give validation.

Conclusion

Converting Python objects to dictionaries is a common task that you can solve in multiple ways. The built-in __dict__ attribute offers a quick hack, while dataclasses.asdict provides a structured, recursive approach. The json module can act as a bridge for simple types, and custom to_dict methods give you full control. When your project demands validation and advanced serialization, look to Pydantic or Marshmallow.

By choosing the right method for your use case, you’ll write clearer, more maintainable code and avoid subtle bugs in serialization. Start with the simplest tool and scale up only when you need more features or safety.


Mateen Kiani
Mateen Kiani
kiani.mateen012@gmail.com
I am a passionate Full stack developer with around 4 years of experience in MERN stack development and 1 year experience in blockchain application development. I have completed several projects in MERN stack, Nextjs and blockchain, including some NFT marketplaces. I have vast experience in Node js, Express, React and Redux.