How to Iterate Over Object Attributes in Python
This guide explores various techniques for iterating over object attributes in Python, covering how to access both instance and class attributes. You'll learn how to use __dict__
, vars()
, and dir()
, and how to filter the attributes you want to iterate over.
Iterating Over Instance Attributes with __dict__
The __dict__
attribute is a dictionary that stores an object's instance-specific attributes (excluding class-level attributes).
class Employee():
cls_id = 'employee'
def __init__(self, name, salary):
self.name = name
self.salary = salary
emp1 = Employee('tomnolan', 100)
for attribute, value in emp1.__dict__.items():
print(attribute, value)
Output:
name tomnolan
salary 100
- This loop prints the key-value pairs for the attributes
name
andsalary
which were set on theEmployee
object.
Iterating Over Instance Attributes with vars()
The vars()
function returns the __dict__
attribute of an object. Thus, you can use the vars()
with the items()
function to iterate over the objects:
class Employee():
cls_id = 'employee'
def __init__(self, name, salary):
self.name = name
self.salary = salary
emp1 = Employee('tomnolan', 100)
for attribute, value in vars(emp1).items():
print(attribute, value)
Output:
name tomnolan
salary 100
- The
vars(emp1)
calls the__dict__
attribute of theemp1
object. - The code then iterates over this dictionary.
- Using the
vars()
method is equivalent to accessing the__dict__
attribute directly, but it is more readable.
Iterating Over All Attributes (Including Class Attributes) with dir()
The dir()
function lists all attributes of an object, including instance attributes, class attributes, and methods. To get the value you then use the getattr()
function, which takes as argument the object, and the name of the attribute.
class Employee():
cls_id = 'employee'
def __init__(self, name, salary):
self.name = name
self.salary = salary
def get_name(self):
return self.name
emp1 = Employee('tomnolan', 100)
for attribute in dir(emp1):
print(attribute, getattr(emp1, attribute))
Output:
__class__ <class '__main__.Employee'>
__delattr__ <method-wrapper '__delattr__' of Employee object at 0x7fc893593f10>
__dict__ {'name': 'tomnolan', 'salary': 100}
__dir__ <built-in method __dir__ of Employee object at 0x7fc893593f10>
__doc__ None
__eq__ <method-wrapper '__eq__' of Employee object at 0x7fc893593f10>
__format__ <built-in method __format__ of Employee object at 0x7fc893593f10>
__ge__ <method-wrapper '__ge__' of Employee object at 0x7fc893593f10>
__getattribute__ <method-wrapper '__getattribute__' of Employee object at 0x7fc893593f10>
__gt__ <method-wrapper '__gt__' of Employee object at 0x7fc893593f10>
__hash__ <method-wrapper '__hash__' of Employee object at 0x7fc893593f10>
__init__ <bound method Employee.__init__ of <__main__.Employee object at 0x7fc893593f10>>
__init_subclass__ <built-in method __init_subclass__ of type object at 0x5582c16e9dd0>
__le__ <method-wrapper '__le__' of Employee object at 0x7fc893593f10>
__lt__ <method-wrapper '__lt__' of Employee object at 0x7fc893593f10>
__module__ __main__
__ne__ <method-wrapper '__ne__' of Employee object at 0x7fc893593f10>
__new__ <built-in method __new__ of type object at 0x7fc893935040>
__reduce__ <built-in method __reduce__ of Employee object at 0x7fc893593f10>
__reduce_ex__ <built-in method __reduce_ex__ of Employee object at 0x7fc893593f10>
__repr__ <method-wrapper '__repr__' of Employee object at 0x7fc893593f10>
__setattr__ <method-wrapper '__setattr__' of Employee object at 0x7fc893593f10>
__sizeof__ <built-in method __sizeof__ of Employee object at 0x7fc893593f10>
__str__ <method-wrapper '__str__' of Employee object at 0x7fc893593f10>
__subclasshook__ <built-in method __subclasshook__ of type object at 0x5582c16e9dd0>
__weakref__ None
cls_id employee
get_name <bound method Employee.get_name of <__main__.Employee object at 0x7fc893593f10>>
name tomnolan
salary 100
- This will list the values for the
name
andsalary
properties which are set in the__init__
method, and will also list the methodget_name()
, and the class attributecls_id
. This is different from the results when we use__dict__
orvars()
which only returned the attributes defined as instance members.
Excluding Attributes Starting with Double Underscores
You can use a list comprehension to filter out built-in attributes (those starting with double underscores __
):
attributes = [attribute for attribute in dir(emp1) if not attribute.startswith('__')]
print(attributes) # Output: ['cls_id', 'get_name', 'name', 'salary']
- The code lists the class attributes whose name does not start with
__
. - You can access each attribute using
getattr(emp1, attribute)
.
Excluding Methods
To only include member variables and exclude methods, use callable()
function in combination with a generator expression to check if a property is a method:
attributes = [attribute for attribute in dir(emp1)
if not attribute.startswith('__')
and not callable(getattr(emp1, attribute))]
print(attributes) # Output: ['cls_id', 'name', 'salary']
Iterating Only Over Class Variables
To iterate over the class's variables (attributes defined directly in the class definition, not inside the init function), pass the class instead of an instance to dir()
:
class Employee():
cls_id = 'employee'
another = 'foo'
def __init__(self, name, salary):
self.name = name
self.salary = salary
class_variables = [attribute for attribute in dir(Employee)
if not attribute.startswith('__')
and not callable(getattr(Employee, attribute))]
print(class_variables) # Output: ['another', 'cls_id']
for attr in class_variables:
print(attr, getattr(Employee, attr))
Output:
another foo
cls_id employee