Fundamentals 9 min read

Understanding Python's __dict__ System, Properties, and Dynamic Attribute Generation

This article explains Python's __dict__ attribute storage, class and instance attributes, demonstrates how to inspect and modify them, introduces properties using the built‑in property() function, and shows dynamic attribute generation with __getattr__, providing clear code examples and explanations.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Understanding Python's __dict__ System, Properties, and Dynamic Attribute Generation

Python treats everything as an object; each object may have multiple attributes. Python provides a unified system for managing these attributes.

Attributes can come from a class definition (class attributes) or be defined on an instance (object attributes). A class may also inherit attributes from its parent class.

All attributes of an object are stored in its __dict__ attribute, which is a dictionary where keys are attribute names and values are the corresponding objects. The following example defines a bird class, a chicken class that inherits from bird , and creates an instance summer of chicken :

<code>class bird(object):
    feather = True

class chicken(bird):
    fly = False
    def __init__(self, age):
        self.age = age

summer = chicken(2)
print(bird.__dict__)
print(chicken.__dict__)
print(summer.__dict__)</code>

The output shows three dictionaries: the first contains attributes of bird (e.g., feather ), the second contains attributes added by chicken (e.g., fly and __init__ ), and the third shows the instance attributes of summer (e.g., age ). Some entries such as __doc__ are automatically generated by Python, and every class ultimately inherits from object .

Python looks up an attribute by traversing the hierarchy from the instance up through its class, parent classes, and finally object . If the same attribute name appears at multiple levels, the lookup stops at the first occurrence (the most derived level).

Attributes can be modified directly or via the __dict__ mapping, which are equivalent approaches:

<code>summer.__dict__['age'] = 3
print(summer.__dict__['age'])

summer.age = 5
print(summer.age)</code>

If you only have an instance and need to discover its class or parent class, you can use summer.__class__ and summer.__class__.__base__ .

Properties

Sometimes an attribute’s value depends on other attributes, and you want changes to one attribute to automatically affect another. Python’s property() built‑in creates such dynamic attributes. For example, we add an adult property to chicken that returns True when age is greater than 1:

<code>class bird(object):
    feather = True

class chicken(bird):
    fly = False
    def __init__(self, age):
        self.age = age
    def getAdult(self):
        if self.age > 1.0:
            return True
        else:
            return False
    adult = property(getAdult)   # property is built‑in

summer = chicken(2)
print(summer.adult)
summer.age = 0.5
print(summer.adult)</code>

The property() function can accept up to four arguments: getter, setter, deleter, and a docstring. The docstring describes the property.

Another example shows a num class with a neg property that always reflects the negative of value . The getter returns -self.value , the setter stores the opposite, and the deleter removes value while printing a message:

<code>class num(object):
    def __init__(self, value):
        self.value = value
    def getNeg(self):
        return -self.value
    def setNeg(self, value):
        self.value = -value
    def delNeg(self):
        print("value also deleted")
        del self.value
    neg = property(getNeg, setNeg, delNeg, "I'm negative")

x = num(1.1)
print(x.neg)
x.neg = -22
print(x.value)
print(num.neg.__doc__)
del x.neg</code>

These examples illustrate how properties encapsulate logic for computed attributes, keeping related state consistent.

Dynamic Attribute Generation with __getattr__

The special method __getattr__(self, name) is invoked when attribute lookup fails in __dict__ . It can generate attributes on the fly. The following class returns True for an adult attribute when age > 1, otherwise False :

<code>class bird(object):
    feather = True

class chicken(bird):
    fly = False
    def __init__(self, age):
        self.age = age
    def __getattr__(self, name):
        if name == 'adult':
            if self.age > 1.0:
                return True
            else:
                return False
        else:
            raise AttributeError(name)

summer = chicken(2)
print(summer.adult)
summer.age = 0.5
print(summer.adult)
print(summer.male)  # raises AttributeError</code>

Each dynamically generated attribute needs its own handling logic inside __getattr__ . Note that Python also provides __getattribute__ , which intercepts all attribute accesses, while __getattr__ only handles missing attributes.

For broader control, __setattr__(self, name, value) and __delattr__(self, name) can be overridden to customize setting and deleting any attribute.

Other Ways to Create Dynamic Attributes

Descriptors (the underlying mechanism of property() ) offer another powerful way to define computed attributes. Interested readers can explore them further.

Summary

The __dict__ attribute stores attributes layer by layer; each layer only keeps the attributes introduced at that level, avoiding duplication of inherited attributes.

Dynamic attribute generation, such as properties and __getattr__ , is a useful concept for managing object state more flexibly in Python development.

Pythonobject-orientedproperty__dict__dynamic attributesattributes
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.