Python Print All Attributes of Object: A Complete Guide
Understanding how to print all attributes of an object in Python is essential for debugging, introspection, and object-oriented programming. When working with complex classes or third-party libraries, developers often need to examine what attributes and methods an object contains. This full breakdown explores multiple techniques to inspect objects and retrieve their complete attribute information.
Most guides skip this. Don't It's one of those things that adds up..
Introduction
Python's dynamic nature allows objects to have attributes that can be added, modified, or removed at runtime. Now, unlike statically typed languages, Python provides powerful introspection capabilities through built-in functions and modules. Knowing how to print all attributes of an object helps developers understand object structure, debug issues, and work effectively with unfamiliar code.
Basic Methods to Print Object Attributes
Using the vars() Function
The vars() function returns the __dict__ attribute of an object, which contains the writable attributes. This is one of the most straightforward approaches:
class Student:
def __init__(self, name, age, grade):
self.name = name
self.age = age
self.grade = grade
student = Student("Alice", 20, "A")
print(vars(student))
# Output: {'name': 'Alice', 'age': 20, 'grade': 'A'}
Important note: vars() only works with objects that have a __dict__ attribute. Built-in types like integers, strings, or tuples don't support this method directly.
Using the dict Attribute
Every Python object has a __dict__ attribute that stores its writable attributes:
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
my_car = Car("Toyota", "Camry", 2023)
print(my_car.__dict__)
# Output: {'make': 'Toyota', 'model': 'Camry', 'year': 2023}
This approach gives you direct access to the object's attribute dictionary, allowing you to manipulate or inspect attributes programmatically.
Using dir() Function for Comprehensive Inspection
The dir() function provides a more extensive view of an object's attributes, including inherited ones:
class Animal:
species = "Mammal"
def __init__(self, name):
self.name = name
def speak(self):
pass
dog = Animal("Buddy")
print(dir(dog))
# Output includes: ['__class__', '__delattr__', '__dict__', '__dir__',
# '__doc__', '__eq__', '__format__', '__ge__',
# '__getattribute__', '__gt__', '__hash__', '__init__',
# '__init_subclass__', '__le__', '__lt__', '__module__',
# '__ne__', '__new__', '__reduce__', '__reduce_ex__',
# '__repr__', '__setattr__', '__sizeof__', '__str__',
# '__subclasshook__', '__weakref__', 'name', 'species',
# 'speak']
While dir() shows all attributes and methods, it includes built-in special methods (those starting and ending with double underscores) Nothing fancy..
Advanced Techniques for Detailed Attribute Inspection
Filtering Only Instance Attributes
To get only the instance-specific attributes (excluding methods and class attributes), combine vars() with additional filtering:
import inspect
class Person:
population = 0
def __init__(self, name, age):
self.age = age
Person.name = name
self.population += 1
def introduce(self):
return f"Hi, I'm {self.
person = Person("John", 30)
# Get only instance attributes
instance_attrs = {k: v for k, v in vars(person).items()
if not k.startswith('_')}
print(instance_attrs)
# Output: {'name': 'John', 'age': 30}
Using inspect Module for Detailed Analysis
The inspect module provides sophisticated tools for examining live objects:
import inspect
class Example:
class_var = "shared"
def __init__(self, value):
self.instance_var = value
def method(self):
return self.instance_var
obj = Example(42)
# Get all members with their types
for name, value in inspect.getmembers(obj):
if not name.startswith('_'):
print(f"{name}: {type(value).__name__}")
This approach categorizes attributes by type, helping distinguish between data attributes and methods.
Retrieving Only Data Attributes
For a cleaner output showing only data attributes (excluding methods), use the inspect module with filtering:
import inspect
def get_data_attributes(obj):
"""Return only data attributes, excluding methods"""
return {name: getattr(obj, name)
for name, value in inspect.getmembers(obj)
if not name.startswith('_')
and not inspect.ismethod(value)
and not inspect.
class Product:
category = "Electronics"
def __init__(self, name, price):
self.name = name
self.price = price
def get_description(self):
return f"{self.name} costs ${self.
product = Product("Laptop", 999)
data_attrs = get_data_attributes(product)
print(data_attrs)
# Output: {'name': 'Laptop', 'price': 999}
Working with Different Types of Objects
Classes vs Instances
Once you need to print all attributes of a class (not an instance), the approach differs slightly:
class Configuration:
debug = True
max_connections = 100
def __init__(self):
self.timeout = 30
# Class attributes
print(Configuration.__dict__)
print(vars(Configuration))
# Instance attributes
config = Configuration()
print(vars(config))
Class attributes are stored in the class's __dict__, while instance attributes are in the instance's __dict__.
Handling Built-in Types
For built-in types that don't have a __dict__ attribute, you need alternative approaches:
# String object
text = "Hello World"
print(dir(text))
print(type(text))
# Custom wrapper for built-in types
class CustomString:
def __init__(self, value):
self.value = value
self.length = len(value)
custom_str = CustomString("Python")
print(vars(custom_str))
Practical Applications and Use Cases
Debugging Complex Objects
When debugging, being able to quickly inspect all attributes helps identify issues:
import json
def debug_object(obj):
"""Pretty print all attributes of an object"""
attrs = {}
for attr in dir(obj):
if not attr.startswith('_'):
try:
attrs[attr] = getattr(obj, attr)
except AttributeError:
attrs[attr] = ""
print(json.dumps(attrs, indent=2, default=str))
class DatabaseConnection:
def __init__(self, host, port, database):
self.Consider this: database = database
self. port = port
self.Now, host = host
self. connected = False
def connect(self):
self.
db = DatabaseConnection("localhost", 5432, "myapp")
debug_object(db)
Creating Object Representations
Implementing custom __repr__ or __str__ methods using attribute inspection:
class Point:
def __init__(self, x, y, z=0):
self.x = x
self.y = y
self.z = z
def __repr__(self):
```python
class Point:
def __init__(self, x, y, z=0):
self.x = x
self.y = y
self.z = z
def __repr__(self):
return f"Point({self.x}, {self.y}, {self.z})"
def __str__(self):
return f"Point at coordinates ({self.That's why x}, {self. y}, {self.
p = Point(1, 2, 3)
print(p) # Uses __str__
print(repr(p)) # Uses __repr__
Mastering the distinction between how class-level and instance-level attributes are stored enables developers to design cleaner data models and more efficient serialization strategies. One common requirement arises when interfacing with external systems—such as REST APIs or configuration files—where complex in-memory objects must be converted into flat, transport-friendly formats like JSON or YAML Still holds up..
By combining attribute inspection with dynamic dictionary generation, we can automate the process of turning any Python object into a structured representation. Consider the following utility function designed to snapshot an object's current state:
import json
class UserProfile:
def __init__(self, name, role, active):
self.That's why name = name
self. role = role
self.
profile = UserProfile("Alice", "Admin", True)
def snapshot_object(obj