Getting attributes 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, getting attributes from a class can mean different things: class attributes, instance attributes, inherited attributes, descriptors, or methods. The best introspection approach depends on what you want to include and how dynamic your objects are. Clear attribute discovery rules make debugging, serialization, and framework integration much more reliable.
Class Attributes vs Instance Attributes
Class attributes live on the class object and are shared. Instance attributes live on each object instance.
If you introspect without distinguishing these two categories, output can be confusing.
Get Instance Attributes Safely
For regular objects, vars(instance) or instance.__dict__ returns instance data attributes.
This is often the right choice for JSON serialization of object state, but it excludes properties computed dynamically and may not work for objects using slots.
Inspect Class Level Members
For class level inspection, use vars(ClassName) or ClassName.__dict__.
This includes methods, descriptors, and metadata, not only business fields. Filter what you need rather than assuming every key is a plain attribute.
Discover Attributes Across Inheritance
dir(obj) returns names from object, class, and inherited classes. It is broad and useful for exploration.
Use getattr to read values dynamically:
Providing a default value avoids exceptions on missing names.
Filter Data Attributes from Callables
If you need only non method attributes:
This includes inherited data and properties while skipping methods.
Be careful with properties, though. Accessing them through getattr can run code, hit the database, or raise errors. For diagnostic tools, you may prefer inspecting descriptors on the class rather than eagerly evaluating every attribute on the instance.
Dataclasses and Typed Models
For dataclasses, use fields for explicit schema based introspection.
This is cleaner than generic reflection when working with structured model objects.
Objects with __slots__
Classes using __slots__ may not have __dict__. In those cases, inspect slot names directly.
If your utility assumes __dict__, it will fail on slot based objects.
Annotations and inspect for Richer Introspection
When class metadata matters, inspect type annotations and descriptors separately from runtime values.
This separation helps tools that generate documentation, validators, or schema mappings.
Practical Serialization Strategy
When building generic serializers, pick one explicit policy:
- only instance
__dict__fields. - include properties.
- include inherited attributes.
Avoid ambiguous reflection helpers that change behavior between classes. Stable policies reduce subtle bugs in API responses and caching logic.
If the object comes from a library, check whether it already exposes a serialization helper before building your own reflection layer. Library specific serializers are often safer than generic attribute walking.
Common Pitfalls
- Mixing class and instance attributes without clear output labeling.
- Assuming
__dict__exists on all objects. - Using
diroutput directly for serialization without filtering callables. - Ignoring inherited attributes when they are semantically important.
- Dynamically reading missing attributes without safe defaults.
Summary
- Decide what kind of attributes you need before choosing introspection tools.
- Use
varsor__dict__for instance state when available. - Use class dictionaries for class level inspection.
- Use
dirandgetattrfor broader reflective discovery. - Handle dataclasses and slot based objects explicitly for robust utilities.

