Python’s .__dict__
is a special attribute in classes and instances that acts as a namespace, mapping attribute names to their corresponding values. You can use .__dict__
to inspect, modify, add, or delete attributes dynamically, which makes it a versatile tool for metaprogramming and debugging.
In this tutorial, you’ll learn about using .__dict__
in various contexts, including classes, instances, and functions. You’ll also explore its role in inheritance with practical examples and comparisons to other tools for manipulating attributes.
By the end of this tutorial, you’ll understand that:
.__dict__
holds an object’s writable attributes, allowing for dynamic manipulation and introspection.- Both
vars()
and.__dict__
let you inspect an object’s attributes. The.__dict__
attribute gives you direct access to the object’s namespace, while thevars()
function returns the object’s.__dict__
. - Common use cases of
.__dict__
include dynamic attribute management, introspection, serialization, and debugging in Python applications.
While this tutorial provides detailed insights into using .__dict__
effectively, having a solid understanding of Python dictionaries and how to use them in your code will help you get the most out of it.
Get Your Code: Click here to download the free sample code you’ll use to learn about using Python’s .dict to work with attributes.
Take the Quiz: Test your knowledge with our interactive “Using Python's .__dict__ to Work With Attributes” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
Using Python's .__dict__ to Work With AttributesIn this quiz, you'll test your understanding of Python's .__dict__ attribute and its usage in classes, instances, and functions. Acting as a namespace, this attribute maps attribute names to their corresponding values and serves as a versatile tool for metaprogramming and debugging.
Getting to Know the .__dict__
Attribute in Python
Python supports the object-oriented programming (OOP) paradigm through classes that encapsulate data (attributes) and behaviors (methods) in a single entity. Under the hood, Python takes advantage of dictionaries to handle these attributes and methods.
Why dictionaries? Because they’re implemented as hash tables, which map keys to values, making lookup operations fast and efficient.
Note: To learn more about using Python dictionaries, check out the following resources:
Generally, Python uses a special dictionary called .__dict__
to maintain references to writable attributes and methods in a Python class or instance. In practice, the .__dict__
attribute is a namespace that maps attribute names to values and method names to method objects.
The .__dict__
attribute is fundamental to Python’s data model. The interpreter recognizes and uses it internally to process classes and objects. It enables dynamic attribute access, addition, removal, and manipulation. You’ll learn how to do these operations in a moment. But first, you’ll look at the differences between the class .__dict__
and the instance .__dict__
.
The .__dict__
Class Attribute
To start learning about .__dict__
in a Python class, you’ll use the following demo class, which has attributes and methods:
demo.py
class DemoClass:
class_attr = "This is a class attribute"
def __init__(self):
self.instance_attr = "This is an instance attribute"
def method(self):
return "This is a method"
In this class, you have a class attribute, two methods, and an instance attribute. Now, start a Python REPL session and run the following code:
>>> from demo import DemoClass
>>> print(DemoClass.__dict__)
{
'__module__': 'demo',
'__firstlineno__': 1,
'class_attr': 'This is a class attribute',
'__init__': <function DemoClass.__init__ at 0x102bcd120>,
'method': <function DemoClass.method at 0x102bcd260>,
'__static_attributes__': ('instance_attr',),
'__dict__': <attribute '__dict__' of 'DemoClass' objects>,
'__weakref__': <attribute '__weakref__' of 'DemoClass' objects>,
'__doc__': None
}
The call to print()
displays a dictionary that maps names to objects. First, you have the '__module__'
key, which maps to a special attribute that specifies where the class is defined. In this case, the class lives in the demo
module. Then, you have the '__firstlineno__'
key, which holds the line number of the first line of the class definition, including decorators. Next, you have the 'class_attr'
key and its corresponding value.
Note: When you access the .__dict__
attribute on a class, you get a mappingproxy
object. This type of object creates a read-only view of a dictionary.
The '__init__'
and 'method'
keys map to the corresponding method objects .__init__()
and .method()
. Next, you have a key called '__dict__'
that maps to the attribute .__dict__
of DemoClass
objects. You’ll explore this attribute more in a moment.
The '__static_attributes__'
key is a tuple containing the names of the attributes that you assign through self.attribute = value
from any method in the class body.
The '__weakref__'
key represents a special attribute that enables you to reference objects without preventing them from being garbage collected.
Finally, you have the '__doc__'
key, which maps to the class’s docstring. If the class doesn’t have a docstring, it defaults to None
.
Did you notice that the .instance_attr
name doesn’t have a key in the class .__dict__
attribute? You’ll find out where it’s hidden in the following section.