How to loop through all the properties of a class?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Python, the right way to loop through all the “properties” of a class depends on what you actually mean by properties. Most of the time, people want the instance attributes stored on an object, and the cleanest way to iterate over those is with vars or __dict__.
Iterate Over Instance Attributes
For normal Python objects, instance data is usually stored in the object dictionary.
That prints each attribute name and value currently stored on the instance.
You can write the same thing with user.__dict__.items(), but vars(user) is a little cleaner and signals intent more clearly.
Understand the Difference Between Class and Instance Data
It is important to separate instance attributes from class attributes.
vars(cfg) includes debug, because that value belongs to the instance. It does not automatically include app_name, because that value lives on the class object itself.
If you want class-level names too, you need a different form of inspection.
Include Class-Level Attributes Carefully
To inspect names defined on the class, you can use vars on the class object.
That will include class attributes and methods. Because of that, you often need filtering if you only want data fields.
Real @property Descriptors Are Different
Python’s @property feature creates computed attributes, not entries in __dict__.
The area value is available on the instance, but it does not appear in vars(rect) because it is computed through the class definition.
If you need to discover @property descriptors, inspect the class:
That pattern finds property descriptors on the class and then reads their values from the instance.
Dataclasses Make Iteration Cleaner
If the class is a dataclass, the standard library gives you field metadata directly.
This is often the best option when you control the class design and want predictable introspection.
Watch Out for __slots__
Some classes use __slots__ instead of an instance dictionary. In that case, vars(obj) may not work because there is no __dict__.
So the “loop through all properties” answer is partly about class design, not just syntax.
Common Pitfalls
A common mistake is using dir(obj) and assuming it returns only data fields. dir returns many names, including methods and inherited members, so it is usually too broad for simple attribute iteration.
Another pitfall is forgetting the difference between instance attributes, class attributes, and computed properties. They live in different places and need different inspection techniques.
Be careful with getattr on computed properties as well. Accessing a property can run code, which may be expensive or have side effects.
Finally, if you just need serialization, do not over-engineer reflection. For plain objects, vars(obj) is often all you need.
Summary
- Use
vars(obj).items()to iterate over normal instance attributes. - Use
vars(MyClass)if you need to inspect class-level names. - '
@propertydescriptors live on the class, not in the instance dictionary.' - Dataclasses provide a clean field API through
dataclasses.fields. - Classes with
__slots__need a different approach because they may not have__dict__.

