Python
member variables
class properties
reflection
object iteration

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.

python
1class User:
2    def __init__(self, name, age):
3        self.name = name
4        self.age = age
5        self.active = True
6
7user = User("Ada", 30)
8
9for key, value in vars(user).items():
10    print(key, value)

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.

python
for key, value in user.__dict__.items():
    print(key, value)

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.

python
1class Config:
2    version = "1.0"
3
4    def __init__(self, debug):
5        self.debug = debug
6
7cfg = Config(True)
8print(vars(cfg))
9print(vars(Config))

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.

python
for name in dir(user):
    if not name.startswith("__"):
        print(name, getattr(user, name))

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.

python
1from dataclasses import dataclass, fields
2
3@dataclass
4class Point:
5    x: int
6    y: int
7
8p = Point(3, 4)
9
10for field in fields(p):
11    print(field.name, getattr(p, field.name))

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.

python
1class Slotted:
2    __slots__ = ("name", "age")
3
4    def __init__(self, name, age):
5        self.name = name
6        self.age = age

For these classes, vars(obj) may fail unless the class explicitly includes __dict__ in its slots. In that case, iterate over __slots__ instead.

python
s = Slotted("Ada", 30)
for name in s.__slots__:
    print(name, getattr(s, name))

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) or obj.__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__.

Course illustration
Course illustration

All Rights Reserved.