How to Use Python __dict__ Attribute

In my years of building large-scale Python applications, I have often needed to peek under the hood of how objects store their data.

One of the most powerful yet misunderstood tools for this is the __dict__ attribute.

Whenever I am debugging complex class hierarchies or building dynamic APIs, __dict__ is my go-to for inspecting object states.

In this tutorial, I will show you exactly how to use the __dict__ attribute in Python classes to manage and manipulate data efficiently.

What is the __dict__ Attribute in Python?

From my experience, the easiest way to think of __dict__ is as a dictionary that stores an object’s (writable) attributes.

Every instance of a class in Python has this internal mapping, which links the attribute names to their values.

I find this incredibly useful when I need to convert an object into a format like JSON for a web service or a database entry.

Access Instance Attributes Using __dict__

When I first started working with Object-Oriented Programming (OOP) in Python, I realized that accessing attributes via the dot notation is just the tip of the iceberg.

Using __dict__, you can see every instance variable at once in a clean, key-value pair format.

Let’s look at a practical example involving a real estate listing in Los Angeles.

class RealEstateListing:
    def __init__(self, property_id, price, location, sq_ft):
        self.property_id = property_id
        self.price = price
        self.location = location
        self.sq_ft = sq_ft

# Creating an instance for a home in Silver Lake, CA
luxury_home = RealEstateListing("LA-90026", 1250000, "Silver Lake", 2400)

# Accessing the instance dictionary
print(luxury_home.__dict__)

You can see the output in the screenshot below.

Use Python __dict__ Attribute

When you run this code, Python returns a dictionary containing all the property details.

I often use this method when I need to quickly verify if all fields in a data model have been correctly populated.

Modify Attributes via the __dict__ Dictionary

One trick I’ve picked up over the years is that __dict__ is not just for reading data; you can actually write to it.

Since it is a standard Python dictionary, you can add or update attributes directly through the dictionary interface.

In this example, let’s update the stock price for a company listed on the New York Stock Exchange.

class StockTicker:
    def __init__(self, symbol, company_name, price):
        self.symbol = symbol
        self.company_name = company_name
        self.price = price

# Portfolio entry for a tech giant
tech_stock = StockTicker("AAPL", "Apple Inc.", 180.50)

# Updating the price directly via __dict__
tech_stock.__dict__['price'] = 185.75

# Adding a new attribute dynamically
tech_stock.__dict__['exchange'] = "NASDAQ"

print(f"Updated Price: {tech_stock.price}")
print(f"Exchange Info: {tech_stock.exchange}")

You can see the output in the screenshot below.

How to Use Python __dict__ Attribute

While I usually prefer standard assignment, using __dict__ is perfect when you are dealing with dynamic attribute names coming from an external configuration file.

Class-Level vs. Instance-Level __dict__

It is a common misconception that __dict__ only exists for instances. I have found that classes themselves have a __dict__ attribute, but it behaves differently than the instance-level one.

The class __dict__ contains the methods and class-level variables defined within that specific class.

class FederalTaxRate:
    tax_year = 2024
    
    def calculate_tax(self, income):
        return income * 0.24

# Viewing the class-level dictionary
print("Class Level Dictionary Keys:")
print(FederalTaxRate.__dict__.keys())

# Viewing the instance-level dictionary
my_tax = FederalTaxRate()
print("\nInstance Level Dictionary:")
print(my_tax.__dict__)

In my workflows, checking the class __dict__ helps introspect inherited methods or check for static variables.

Use __dict__ for Dynamic Object Creation

There are times when I receive a large batch of data, perhaps from a CSV of National Park statistics, and I need to turn those rows into objects.

Instead of mapping every column manually, I use __dict__.update() to populate the object in one go.

class NationalPark:
    def __init__(self, park_data):
        # Dynamically updating the instance dictionary
        self.__dict__.update(park_data)

# Data received from an API or CSV
yellowstone_data = {
    "name": "Yellowstone",
    "state": "Wyoming",
    "established": 1872,
    "area_acres": 2219791
}

park_obj = NationalPark(yellowstone_data)

print(f"Park Name: {park_obj.name}")
print(f"Acres: {park_obj.area_acres}")

You can see the output in the screenshot below.

Python __dict__ Attribute

This approach saves me a massive amount of boilerplate code, especially when the data structure changes frequently.

Difference Between vars() and __dict__

In my code reviews, I often see developers use vars(object) instead of object.__dict__.

Functionally, they do the same thing: vars() is simply a built-in function that returns the __dict__ attribute of an object.

I personally find vars() a bit more readable and “Pythonic” in most general scripts.

class Car:
    def __init__(self, make, model):
        self.make = make
        self.model = model

ford_truck = Car("Ford", "F-150")

# These two lines are equivalent
print(vars(ford_truck))
print(ford_truck.__dict__)

I suggest using vars() when you want clean code, and reserving __dict__ for when you are performing deep metaprogramming tasks.

Limitations: When __dict__ is Missing (__slots__)

I have encountered specific scenarios where an object does not have a __dict__ attribute at all. This happens when a class uses __slots__ to save memory.

If you are building an application that handles millions of objects—like a flight tracking system for Hartsfield-Jackson Airport—you might use __slots__.

class Flight:
    __slots__ = ['flight_number', 'destination']
    
    def __init__(self, flight_number, destination):
        self.flight_number = flight_number
        self.destination = destination

delta_flight = Flight("DL123", "Atlanta")

try:
    print(delta_flight.__dict__)
except AttributeError:
    print("This object has no __dict__ because it uses __slots__.")

I always double-check for __slots__ before accessing __dict__ in library-level code to avoid runtime errors.

Handle Nested Objects and Serialization

One of the best uses for __dict__ I’ve found is converting complex class structures into simple dictionaries for JSON serialization.

If you have a class that represents a United States Census record, you can easily turn that record into a format readable by a front-end dashboard.

class CensusRecord:
    def __init__(self, city, population, state):
        self.city = city
        self.population = population
        self.state = state

    def to_dict(self):
        return self.__dict__

nyc_census = CensusRecord("New York City", 8336000, "NY")
print(nyc_census.to_dict())

However, be careful if your class contains other objects, as __dict__ will only return the reference to those objects, not a nested dictionary.

Use __dict__ for Custom Debugging Tools

Whenever I am building a custom framework, I like to create a “pretty print” method for my objects.

By iterating over __dict__.items(), you can create a clear summary of any object’s current state.

class Employee:
    def __init__(self, name, role, department):
        self.name = name
        self.role = role
        self.department = department

    def debug_info(self):
        print("--- Employee Object Debug ---")
        for key, value in self.__dict__.items():
            print(f"{key.capitalize()}: {value}")

emp = Employee("Sarah Smith", "Software Engineer", "Cloud Infrastructure")
emp.debug_info()

This simple loop has saved me hours of digging through log files during late-night deployment sessions.

Common Issues to Avoid

Throughout my career, I have seen a few common mistakes when using __dict__.

One is forgetting that __dict__ only tracks instance variables, not class variables or properties defined with the @property decorator.

Another is trying to use __dict__ on built-in types like integers or lists; these do not have a __dict__ attribute.

I recommend always using hasattr(obj, ‘__dict__’) when writing a function that needs to process many different data types.

In this guide, I have covered how the __dict__ attribute works and how you can use it to make your Python code more dynamic.

I find that once you understand the dictionary-like nature of Python objects, you can write much more flexible and powerful programs.

You may also read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.