looping over all member variables of a class in python
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Looping over all member variables of a Python object depends on what you mean by "member variables." Instance attributes, class attributes, properties, and dynamically generated descriptors are not all stored in the same place. In most practical code, if you want the writable attributes on one instance, vars(obj) or obj.__dict__ is the cleanest starting point.
Iterate Over Instance Attributes with vars
For a normal instance, vars(obj) returns the instance attribute dictionary.
This is usually the most direct and readable answer when the goal is to inspect or serialize instance state.
You can also use user.__dict__ directly.
vars(user) is often preferred because it communicates intent more clearly.
Class Attributes Are Different
Class-level attributes live on the class object, not in the instance dictionary.
If you need class attributes too, inspect the class separately. Mixing them blindly with instance state can be confusing because methods and descriptors are also present on the class.
Filter dir When You Need a Broader View
dir(obj) shows more than just data attributes. It includes methods, inherited names, and special attributes.
This is useful for introspection, but it is broader and noisier than vars(obj). Use it when you intentionally want properties, inherited members, or descriptor-backed values, not just simple stored attributes.
Dataclasses Give You a Better Structured Option
If the object is a dataclass, prefer fields() for declared data members.
This is often better than introspecting __dict__ because it reflects the declared model structure rather than whatever attributes happen to exist at runtime.
Watch Out for __slots__
Not every class has a __dict__. Classes that use __slots__ may store attributes differently.
For these classes, vars(obj) may fail unless the class explicitly includes __dict__ in its slots. In that case, iterate over __slots__ instead.
This is a good example of why "all member variables" is not one universal Python operation. The storage model depends on how the class was designed, so introspection code should match the kind of object it is inspecting. That small distinction prevents a lot of confusing reflection code.
Common Pitfalls
A common mistake is assuming dir(obj) and vars(obj) are interchangeable. They are not. dir is broad introspection, while vars usually means stored instance attributes.
Another is forgetting about class attributes and expecting them to appear in obj.__dict__.
Developers also sometimes assume every object has a writable __dict__, which breaks on slotted classes.
Summary
- Use
vars(obj)orobj.__dict__to iterate over normal instance attributes. - Inspect the class separately if you also need class attributes.
- Use
dir(obj)only when you intentionally want a broader introspection view. - Prefer
dataclasses.fields()for dataclass models. - Remember that slotted classes may not have a normal instance
__dict__.

