⚙️ Object Methods
Object methods are functions that belong to objects and define what actions those objects can perform. While attributes store data about objects, methods provide the behaviors and functionality that make objects useful and interactive. Understanding methods transforms static data containers into dynamic, responsive entities.
Think of methods as the "verbs" of your objects - if a car object has attributes like color and speed, its methods might include start(), stop(), and accelerate(). Methods bridge the gap between data and action.
# Methods give objects behavior
class Calculator:
def __init__(self):
self.result = 0
def add(self, number):
self.result += number
return self.result
def multiply(self, number):
self.result *= number
return self.result
def clear(self):
self.result = 0
return "Calculator cleared"
calc = Calculator()
print(calc.add(5)) # 5
print(calc.multiply(3)) # 15
print(calc.clear()) # Calculator cleared
🎯 Understanding Object Methods
Methods are functions defined inside classes that operate on object data. They have access to the object's attributes through the special self
parameter, allowing them to read and modify the object's state.
Defining Methods
Methods are defined similar to regular functions but must include self
as the first parameter. This parameter gives methods access to the object's attributes and other methods within the same class.
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
def get_balance(self): # Method with no additional parameters
return f"{self.owner}'s balance: ${self.balance}"
def deposit(self, amount): # Method with parameter
if amount > 0:
self.balance += amount
return f"Deposited ${amount}. New balance: ${self.balance}"
return "Invalid deposit amount"
def transfer(self, other_account, amount): # Method with multiple parameters
if amount <= self.balance:
self.balance -= amount
other_account.balance += amount
return f"Transferred ${amount} to {other_account.owner}"
return "Insufficient funds"
# Using methods
alice_account = BankAccount("Alice", 100)
bob_account = BankAccount("Bob", 50)
print(alice_account.deposit(25))
print(alice_account.transfer(bob_account, 30))
print(bob_account.get_balance())
The Self Parameter
The self
parameter is Python's way of giving methods access to the object they belong to. When you call a method, Python automatically passes the object as the first argument.
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
self.courses = []
def add_course(self, course):
# self refers to the specific student object
self.courses.append(course)
return f"{self.name} enrolled in {course}"
def get_info(self):
# self allows access to all object attributes
course_list = ", ".join(self.courses) if self.courses else "None"
return f"Student: {self.name}, Grade: {self.grade}, Courses: {course_list}"
# Each object gets its own 'self'
student1 = Student("Alice", "A")
student2 = Student("Bob", "B")
print(student1.add_course("Math")) # self = student1
print(student2.add_course("Science")) # self = student2
print(student1.get_info()) # self = student1
⚡ Method Parameters and Return Values
Methods can accept parameters just like regular functions, and they can return values to provide feedback or computed results. This flexibility allows methods to be interactive and responsive to different inputs.
Methods with Parameters
Parameters allow methods to receive external data and modify their behavior accordingly.
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def resize(self, new_width, new_height):
old_area = self.width * self.height
self.width = new_width
self.height = new_height
new_area = self.width * self.height
return f"Resized from {old_area} to {new_area} square units"
def scale(self, factor):
self.width *= factor
self.height *= factor
return f"Scaled by {factor}x. New size: {self.width}x{self.height}"
def is_larger_than(self, other_rectangle):
my_area = self.width * self.height
other_area = other_rectangle.width * other_rectangle.height
return my_area > other_area
rect1 = Rectangle(4, 3)
rect2 = Rectangle(5, 2)
print(rect1.resize(6, 4))
print(rect1.scale(2))
print(rect1.is_larger_than(rect2))
Methods with Return Values
Return values allow methods to provide feedback, computed results, or status information.
class ShoppingCart:
def __init__(self):
self.items = {}
def add_item(self, item, price, quantity=1):
if item in self.items:
self.items[item]['quantity'] += quantity
else:
self.items[item] = {'price': price, 'quantity': quantity}
return f"Added {quantity} {item}(s) to cart"
def get_total(self):
total = 0
for item_data in self.items.values():
total += item_data['price'] * item_data['quantity']
return total
def get_summary(self):
if not self.items:
return "Cart is empty"
summary = []
for item, data in self.items.items():
line = f"{item}: ${data['price']} x {data['quantity']}"
summary.append(line)
return {
'items': summary,
'total': self.get_total(),
'item_count': len(self.items)
}
cart = ShoppingCart()
cart.add_item("Apple", 1.50, 3)
cart.add_item("Bread", 2.99)
print(f"Total: ${cart.get_total()}")
summary = cart.get_summary()
for item in summary['items']:
print(item)
🚀 Special Methods (Magic Methods)
Python provides special methods that enable objects to work with built-in functions and operators. These methods have double underscores and unlock powerful functionality for your objects.
String Representation Methods
The __str__
and __repr__
methods control how objects appear when printed or converted to strings.
class Product:
def __init__(self, name, price, stock):
self.name = name
self.price = price
self.stock = stock
def __str__(self): # For end users
return f"{self.name} - ${self.price}"
def __repr__(self): # For developers
return f"Product('{self.name}', {self.price}, {self.stock})"
def __len__(self): # Enable len() function
return self.stock
# Special methods in action
laptop = Product("Laptop", 999, 5)
print(laptop) # Uses __str__
print(repr(laptop)) # Uses __repr__
print(len(laptop)) # Uses __len__
print(f"Stock: {len(laptop)} units")
Comparison and Arithmetic Methods
Special methods enable your objects to work with comparison operators and arithmetic operations.
class Score:
def __init__(self, points):
self.points = points
def __str__(self):
return f"{self.points} points"
def __eq__(self, other): # Enable == comparison
return self.points == other.points
def __lt__(self, other): # Enable < comparison
return self.points < other.points
def __add__(self, other): # Enable + operation
return Score(self.points + other.points)
def __sub__(self, other): # Enable - operation
return Score(self.points - other.points)
# Using comparison and arithmetic
score1 = Score(100)
score2 = Score(85)
print(f"Score 1: {score1}")
print(f"Score 2: {score2}")
print(f"Equal? {score1 == score2}")
print(f"Score 1 higher? {score1 > score2}")
print(f"Combined: {score1 + score2}")
print(f"Difference: {score1 - score2}")
Essential Method Patterns
Common method patterns solve recurring design problems and create consistent interfaces across different classes.
Pattern | Purpose | Example |
---|---|---|
Factory Methods | Create objects with specific configurations | create_admin_user() |
Validation Methods | Check object state or input validity | is_valid_email() |
Conversion Methods | Transform object to different formats | to_json() , to_dict() |
Utility Methods | Provide helper functionality | calculate_age() |
Event Methods | Handle state changes or notifications | on_item_added() |
🌟 Method Organization and Best Practices
Well-organized methods make classes easier to understand, test, and maintain. Following established patterns helps create professional, reusable code.
Method Categories
Organize methods into logical categories based on their purpose and responsibility.
class TaskManager:
def __init__(self):
self.tasks = []
self.completed_count = 0
# Creation/Modification methods
def add_task(self, description, priority="medium"):
task = {
'id': len(self.tasks) + 1,
'description': description,
'priority': priority,
'completed': False
}
self.tasks.append(task)
return f"Added task {task['id']}: {description}"
def complete_task(self, task_id):
for task in self.tasks:
if task['id'] == task_id and not task['completed']:
task['completed'] = True
self.completed_count += 1
return f"Completed task {task_id}"
return "Task not found or already completed"
# Query methods
def get_pending_tasks(self):
return [task for task in self.tasks if not task['completed']]
def get_completed_tasks(self):
return [task for task in self.tasks if task['completed']]
def get_task_count(self):
return len(self.tasks)
# Display methods
def show_summary(self):
pending = len(self.get_pending_tasks())
return f"Tasks: {pending} pending, {self.completed_count} completed"
# Well-organized method usage
manager = TaskManager()
manager.add_task("Learn Python", "high")
manager.add_task("Buy groceries", "low")
manager.complete_task(1)
print(manager.show_summary())
print(f"Pending tasks: {len(manager.get_pending_tasks())}")
💡 Practical Applications
Building Interactive Objects
Methods enable objects to respond to user actions and maintain their state appropriately.
class GameCharacter:
def __init__(self, name, health=100):
self.name = name
self.health = health
self.max_health = health
self.level = 1
self.experience = 0
def take_damage(self, damage):
self.health = max(0, self.health - damage)
if self.health == 0:
return f"{self.name} has been defeated!"
return f"{self.name} took {damage} damage. Health: {self.health}/{self.max_health}"
def heal(self, amount):
self.health = min(self.max_health, self.health + amount)
return f"{self.name} healed {amount} HP. Health: {self.health}/{self.max_health}"
def gain_experience(self, xp):
self.experience += xp
if self.experience >= self.level * 100:
return self.level_up()
return f"{self.name} gained {xp} XP"
def level_up(self):
self.level += 1
self.max_health += 20
self.health = self.max_health
self.experience = 0
return f"{self.name} leveled up! Now level {self.level}"
def get_status(self):
return f"{self.name} - Level {self.level} - HP: {self.health}/{self.max_health} - XP: {self.experience}"
# Interactive character
hero = GameCharacter("Hero")
print(hero.take_damage(30))
print(hero.heal(15))
print(hero.gain_experience(150))
print(hero.get_status())
Hands-on Exercise
Create a simple Calculator class with methods for basic math operations. Include methods for addition, subtraction, multiplication, division, and getting the last result. Store the result of operations in the calculator.
class Calculator:
def __init__(self):
# TODO: Initialize result attribute
pass
def add(self, number):
# TODO: Add number to result
pass
def subtract(self, number):
# TODO: Subtract number from result
pass
def multiply(self, number):
# TODO: Multiply result by number
pass
def divide(self, number):
# TODO: Divide result by number (handle division by zero)
pass
def get_result(self):
# TODO: Return current result
pass
def clear(self):
# TODO: Reset result to 0
pass
# TODO: Test your calculator
calc = Calculator()
print(f"Initial result: {calc.get_result()}")
calc.add(10)
print(f"After adding 10: {calc.get_result()}")
calc.multiply(2)
print(f"After multiplying by 2: {calc.get_result()}")
calc.subtract(5)
print(f"After subtracting 5: {calc.get_result()}")
Solution and Explanation 💡
Click to see the complete solution
class Calculator:
def __init__(self):
# Initialize result attribute
self.result = 0
def add(self, number):
# Add number to result
self.result += number
return self.result
def subtract(self, number):
# Subtract number from result
self.result -= number
return self.result
def multiply(self, number):
# Multiply result by number
self.result *= number
return self.result
def divide(self, number):
# Divide result by number (handle division by zero)
if number != 0:
self.result /= number
return self.result
else:
print("Error: Cannot divide by zero")
return self.result
def get_result(self):
# Return current result
return self.result
def clear(self):
# Reset result to 0
self.result = 0
return self.result
# Test your calculator
calc = Calculator()
print(f"Initial result: {calc.get_result()}")
calc.add(10)
print(f"After adding 10: {calc.get_result()}")
calc.multiply(2)
print(f"After multiplying by 2: {calc.get_result()}")
calc.subtract(5)
print(f"After subtracting 5: {calc.get_result()}")
Key Learning Points:
- 📌 Instance attributes: Use
self.result
to store calculator's current state - 📌 Method chaining: Return values allow methods to be used in sequence
- 📌 State management: Object maintains its state between method calls
- 📌 Error handling: Check for invalid operations like division by zero
- 📌 Method organization: Group related functionality in logical methods
Learn more about class inheritance to discover how to build upon existing classes and create specialized versions.
Test Your Knowledge
Test what you've learned about object methods:
What's Next?
Now that you understand how to create powerful object methods, you're ready to learn about class inheritance. Inheritance allows you to build upon existing classes and create specialized versions without starting from scratch.
Ready to continue? Check out our lesson on Class Inheritance.
Was this helpful?
Track Your Learning Progress
Sign in to bookmark tutorials and keep track of your learning journey.
Your progress is saved automatically as you read.