Object-Oriented Programming (OOP) in Python relies heavily on instance data, i.e. variables that belong to a specific object rather than the class itself. Whether you are building simple data structures or complex systems, knowing how to read and write these attributes is fundamental.
This guide explains the standard techniques to access and modify instance variables, including the common dot notation and dynamic methods for more advanced scenarios.
Understanding Instance Data
In Python, a class is a blueprint, and an object is an instance of that blueprint. Data stored within an object (usually defined inside the __init__ method using self) is unique to that specific instance.
class Car:
def __init__(self, make, model):
self.make = make
self.model = model
my_car = Car("Toyota", "Corolla")Method 1: Dot Notation (Standard Approach)
The most direct and readable way to interact with an object is using dot notation (object.attribute). This is used when you know the name of the attribute while writing the code.
Accessing Data
To retrieve a value, simply append .attribute_name to your object variable.
class Car:
def __init__(self, make, year):
self.make = make
self.year = year
my_car = Car("Toyota", 2020)
print(f"Make: {my_car.make}")
print(f"Year: {my_car.year}")Output:
Make: Toyota
Year: 2020Modifying Data
Python objects are mutable by default. You can change an attribute's value by assigning a new value to it via dot notation.
print(f"Original Year: {my_car.year}")
my_car.year = 2025
print(f"Modified Year: {my_car.year}")Output:
Original Year: 2020
Modified Year: 2025Method 2: Dynamic Access with getattr / setattr
Sometimes you may not know the attribute name until runtime (e.g., the attribute name is stored in a string variable from user input). Python provides built-in functions to handle this.
Using getattr() to Read
getattr(object, "string_name") is equivalent to object.string_name.
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
book = Book("The Great Gatsby", "F. Scott Fitzgerald")
attr_to_find = "author"
value = getattr(book, attr_to_find)
print(f"Value of '{attr_to_find}': {value}")Output:
Value of 'author': F. Scott FitzgeraldUsing setattr() to Write
setattr(object, "string_name", value) is equivalent to object.string_name = value.
setattr(book, "title", "New Title Edition")
print(f"Updated Title: {book.title}")Output:
Updated Title: New Title EditionHandling Missing Attributes (AttributeError)
A common error occurs when trying to access an attribute that was never defined or contains a typo.
Reproducing the Error
class Student:
def __init__(self, name):
self.name = name
student = Student("Alice")
try:
print(student.grade)
except AttributeError as e:
print(f"Error: {e}")Output:
Error: 'Student' object has no attribute 'grade'Solution: Using getattr Defaults or try-except
You can prevent crashes by providing a default value to getattr, which is cleaner than a try-except block for simple reads.
grade = getattr(student, "grade", "Not Graded")
print(f"Student Grade: {grade}")
student.grade = 95
print(f"Assigned Grade: {student.grade}")Output:
Student Grade: Not Graded
Assigned Grade: 95Conclusion
Manipulating instance data is the core of Python OOP.
- Use Dot Notation (
obj.attr) for clear, standard access. - Use
getattr()andsetattr()when attribute names are dynamic strings. - Use
getattr(obj, name, default)to safely read attributes that might be missing without raising anAttributeError.