Classes and Methods: Python Basics

This content contains beginner-friendly Python code examples focused on understanding classes and instance methods. These examples demonstrate how Python organizes code into classes and objects, showing the fundamental building blocks of object-oriented programming in Python.

How to Read These Examples

  1. Start with the class definition - Understand what data the object will hold
  2. Follow the __init__ method - See how objects are created and initialized
  3. Trace method calls - Follow how methods access and modify object attributes
  4. Notice the self parameter - See how methods reference the current object
  5. Practice Pythonic thinking - Understand Python’s approach to object-oriented programming

Example 1: Simple Student Class with Basic Methods

Code to Read:

  1class Student:
  2    """A simple class to represent a student"""
  3    
  4    def __init__(self, name, age, grade):
  5        """Initialize a new student object"""
  6        self.name = name        # Instance attribute
  7        self.age = age
  8        self.grade = grade
  9        self.courses = []       # Start with empty course list
 10        self.is_enrolled = True
 11    
 12    def get_name(self):
 13        """Return the student's name"""
 14        return self.name
 15    
 16    def get_age(self):
 17        """Return the student's age"""
 18        return self.age
 19    
 20    def get_grade(self):
 21        """Return the student's grade level"""
 22        return self.grade
 23    
 24    def is_student_enrolled(self):
 25        """Check if student is currently enrolled"""
 26        return self.is_enrolled
 27    
 28    def add_course(self, course_name):
 29        """Add a course to the student's schedule"""
 30        if course_name not in self.courses:
 31            self.courses.append(course_name)
 32            print(f"Added {course_name} to {self.name}'s schedule")
 33        else:
 34            print(f"{self.name} is already enrolled in {course_name}")
 35    
 36    def drop_course(self, course_name):
 37        """Remove a course from the student's schedule"""
 38        if course_name in self.courses:
 39            self.courses.remove(course_name)
 40            print(f"Dropped {course_name} from {self.name}'s schedule")
 41        else:
 42            print(f"{self.name} is not enrolled in {course_name}")
 43    
 44    def get_courses(self):
 45        """Return a copy of the student's course list"""
 46        return self.courses.copy()
 47    
 48    def get_course_count(self):
 49        """Return the number of courses the student is taking"""
 50        return len(self.courses)
 51    
 52    def withdraw(self):
 53        """Withdraw the student from school"""
 54        self.is_enrolled = False
 55        self.courses = []  # Clear all courses
 56        print(f"{self.name} has withdrawn from school")
 57    
 58    def re_enroll(self):
 59        """Re-enroll the student"""
 60        self.is_enrolled = True
 61        print(f"{self.name} has re-enrolled in school")
 62    
 63    def get_info(self):
 64        """Return formatted information about the student"""
 65        status = "Enrolled" if self.is_enrolled else "Withdrawn"
 66        course_list = ", ".join(self.courses) if self.courses else "None"
 67        return f"{self.name} (Age: {self.age}, Grade: {self.grade}, Status: {status}, Courses: {course_list})"
 68
 69# Using the Student class
 70def demo_student_class():
 71    """Demonstrate how to use the Student class"""
 72    
 73    # Create student objects
 74    alice = Student("Alice Johnson", 16, 10)
 75    bob = Student("Bob Smith", 17, 11)
 76    
 77    # Use methods to access information
 78    print("=== Student Information ===")
 79    print(f"Student name: {alice.get_name()}")
 80    print(f"Alice's age: {alice.get_age()}")
 81    print(f"Bob's grade: {bob.get_grade()}")
 82    print()
 83    
 84    # Add courses
 85    print("=== Adding Courses ===")
 86    alice.add_course("Math")
 87    alice.add_course("English")
 88    alice.add_course("Science")
 89    bob.add_course("History")
 90    bob.add_course("Math")
 91    print()
 92    
 93    # Display course information
 94    print("=== Course Information ===")
 95    print(f"Alice's courses: {alice.get_courses()}")
 96    print(f"Alice is taking {alice.get_course_count()} courses")
 97    print(f"Bob's courses: {bob.get_courses()}")
 98    print()
 99    
100    # Modify student status
101    print("=== Status Changes ===")
102    alice.drop_course("Science")
103    bob.withdraw()
104    print()
105    
106    # Show final information
107    print("=== Final Student Info ===")
108    print(alice.get_info())
109    print(bob.get_info())
110
111# Run the demo
112if __name__ == "__main__":
113    demo_student_class()

What to Notice:

Details
  • Class keyword: class Student: defines a new class
  • __init__ method: Special method that runs when creating new objects
  • self parameter: Always the first parameter in instance methods - refers to the current object
  • Instance attributes: self.name, self.age store data specific to each object
  • Default values: self.courses = [] sets up initial state
Details
  • self in every method: All instance methods must have self as first parameter
  • Accessing attributes: self.name refers to the current object’s name attribute
  • Method naming: Python uses snake_case for method names (unlike Java’s camelCase)
  • Return values: Methods can return data or modify object state
  • No explicit typing: Python doesn’t require type declarations
Details
  • Separate objects: alice and bob are independent Student objects
  • Individual attributes: Each object has its own name, age, courses list
  • State changes: Methods modify the specific object they’re called on
  • List attributes: Each object gets its own separate courses list

Trace Through Example:

 1# Object creation:
 2alice = Student("Alice Johnson", 16, 10)
 3# 1. Python calls Student.__init__(alice, "Alice Johnson", 16, 10)
 4# 2. alice.name = "Alice Johnson"
 5# 3. alice.age = 16
 6# 4. alice.grade = 10
 7# 5. alice.courses = []
 8# 6. alice.is_enrolled = True
 9
10# Method calls:
11alice.get_name()  # → returns "Alice Johnson"
12alice.add_course("Math")
13# 1. Check if "Math" not in alice.courses → True
14# 2. alice.courses.append("Math") → courses becomes ["Math"]
15# 3. Print confirmation message
16
17alice.get_course_count()  # → returns len(alice.courses) → 1

Example 2: Simple Calculator Class with Mathematical Operations

Code to Read:

  1class Calculator:
  2    """A simple calculator that remembers its result"""
  3    
  4    def __init__(self):
  5        """Initialize calculator with zero result"""
  6        self.result = 0.0
  7        self.history = []  # Keep track of operations
  8    
  9    def get_result(self):
 10        """Return the current result"""
 11        return self.result
 12    
 13    def get_history(self):
 14        """Return a copy of the operation history"""
 15        return self.history.copy()
 16    
 17    def clear(self):
 18        """Reset calculator to zero"""
 19        self.result = 0.0
 20        self.history.append("CLEAR")
 21        print("Calculator cleared")
 22    
 23    def add(self, number):
 24        """Add a number to the current result"""
 25        self.result += number
 26        operation = f"{self.result - number} + {number} = {self.result}"
 27        self.history.append(operation)
 28        print(operation)
 29        return self.result
 30    
 31    def subtract(self, number):
 32        """Subtract a number from the current result"""
 33        old_result = self.result
 34        self.result -= number
 35        operation = f"{old_result} - {number} = {self.result}"
 36        self.history.append(operation)
 37        print(operation)
 38        return self.result
 39    
 40    def multiply(self, number):
 41        """Multiply the current result by a number"""
 42        old_result = self.result
 43        self.result *= number
 44        operation = f"{old_result} × {number} = {self.result}"
 45        self.history.append(operation)
 46        print(operation)
 47        return self.result
 48    
 49    def divide(self, number):
 50        """Divide the current result by a number"""
 51        if number == 0:
 52            print("Error: Cannot divide by zero!")
 53            return self.result
 54        
 55        old_result = self.result
 56        self.result /= number
 57        operation = f"{old_result} ÷ {number} = {self.result}"
 58        self.history.append(operation)
 59        print(operation)
 60        return self.result
 61    
 62    def set_value(self, number):
 63        """Set the calculator to a specific value"""
 64        self.result = number
 65        operation = f"SET {number}"
 66        self.history.append(operation)
 67        print(f"Calculator set to {number}")
 68        return self.result
 69    
 70    def square(self):
 71        """Square the current result"""
 72        old_result = self.result
 73        self.result = self.result ** 2
 74        operation = f"{old_result}² = {self.result}"
 75        self.history.append(operation)
 76        print(operation)
 77        return self.result
 78    
 79    def sqrt(self):
 80        """Take the square root of the current result"""
 81        if self.result < 0:
 82            print("Error: Cannot take square root of negative number!")
 83            return self.result
 84        
 85        old_result = self.result
 86        self.result = self.result ** 0.5
 87        operation = f"√{old_result} = {self.result}"
 88        self.history.append(operation)
 89        print(operation)
 90        return self.result
 91
 92# Using the Calculator class
 93def demo_calculator():
 94    """Demonstrate calculator functionality"""
 95    
 96    # Create calculator objects
 97    calc1 = Calculator()
 98    calc2 = Calculator()
 99    
100    print("=== Calculator 1 ===")
101    calc1.set_value(10)
102    calc1.add(5)
103    calc1.multiply(3)
104    calc1.subtract(20)
105    print(f"Final result: {calc1.get_result()}")
106    print()
107    
108    print("=== Calculator 2 ===")
109    calc2.set_value(16)
110    calc2.sqrt()
111    calc2.square()
112    calc2.divide(4)
113    print(f"Final result: {calc2.get_result()}")
114    print()
115    
116    # Show operation history
117    print("=== Operation History ===")
118    print("Calculator 1 history:")
119    for operation in calc1.get_history():
120        print(f"  {operation}")
121    
122    print("Calculator 2 history:")
123    for operation in calc2.get_history():
124        print(f"  {operation}")
125    
126    # Demonstrate error handling
127    print("\n=== Error Handling ===")
128    calc1.divide(0)  # Should show error message
129    calc1.clear()
130    calc1.subtract(5)
131    calc1.sqrt()     # Should show error for negative number
132
133# Run the demo
134if __name__ == "__main__":
135    demo_calculator()

What to Notice:

Details
  • Persistent state: Calculator remembers its result between operations
  • History tracking: self.history list accumulates all operations
  • State validation: Methods check for invalid operations (divide by zero)
  • Independent calculators: Each Calculator object has its own result and history
Details
  • Returning results: Most methods return self.result for convenience
  • Method chaining potential: Returned values could be used for chaining operations
  • Side effects: Methods both modify state and provide user feedback
  • Error handling: Methods handle edge cases and continue operation
Details
  • List methods: Using .append() to add to history
  • String formatting: Using f-strings for operation descriptions
  • Exponentiation: Using ** operator for squares and square roots
  • Copy method: self.history.copy() prevents external modification

Example 3: Library Book Class with Status Tracking

Code to Read:

  1class LibraryBook:
  2    """A class to represent a book in a library system"""
  3    
  4    def __init__(self, title, author, isbn):
  5        """Initialize a new library book"""
  6        self.title = title
  7        self.author = author
  8        self.isbn = isbn
  9        self.is_available = True
 10        self.borrowed_by = None
 11        self.borrow_count = 0
 12        self.borrow_history = []
 13    
 14    def get_title(self):
 15        """Return the book's title"""
 16        return self.title
 17    
 18    def get_author(self):
 19        """Return the book's author"""
 20        return self.author
 21    
 22    def get_isbn(self):
 23        """Return the book's ISBN"""
 24        return self.isbn
 25    
 26    def is_book_available(self):
 27        """Check if the book is available for borrowing"""
 28        return self.is_available
 29    
 30    def get_borrowed_by(self):
 31        """Return who currently has the book borrowed"""
 32        return self.borrowed_by
 33    
 34    def get_borrow_count(self):
 35        """Return how many times the book has been borrowed"""
 36        return self.borrow_count
 37    
 38    def borrow_book(self, borrower_name):
 39        """Allow someone to borrow the book"""
 40        if not self.is_available:
 41            print(f"Sorry, '{self.title}' is already borrowed by {self.borrowed_by}")
 42            return False
 43        
 44        self.is_available = False
 45        self.borrowed_by = borrower_name
 46        self.borrow_count += 1
 47        self.borrow_history.append(f"Borrowed by {borrower_name}")
 48        print(f"'{self.title}' has been borrowed by {borrower_name}")
 49        return True
 50    
 51    def return_book(self):
 52        """Return the book to the library"""
 53        if self.is_available:
 54            print(f"'{self.title}' is already available in the library")
 55            return False
 56        
 57        returner = self.borrowed_by
 58        self.is_available = True
 59        self.borrowed_by = None
 60        self.borrow_history.append(f"Returned by {returner}")
 61        print(f"'{self.title}' has been returned by {returner}")
 62        return True
 63    
 64    def get_popularity_level(self):
 65        """Determine how popular the book is based on borrow count"""
 66        if self.borrow_count == 0:
 67            return "New/Unread"
 68        elif self.borrow_count <= 3:
 69            return "Low popularity"
 70        elif self.borrow_count <= 10:
 71            return "Moderate popularity"
 72        elif self.borrow_count <= 20:
 73            return "Popular"
 74        else:
 75            return "Very popular"
 76    
 77    def get_book_status(self):
 78        """Return a detailed status of the book"""
 79        availability = "Available" if self.is_available else f"Borrowed by {self.borrowed_by}"
 80        return f"'{self.title}' by {self.author} - {availability} (Borrowed {self.borrow_count} times)"
 81    
 82    def get_borrow_history(self):
 83        """Return the complete borrowing history"""
 84        return self.borrow_history.copy()
 85
 86# Using the LibraryBook class
 87def demo_library_system():
 88    """Demonstrate library book management"""
 89    
 90    # Create book objects
 91    book1 = LibraryBook("The Great Gatsby", "F. Scott Fitzgerald", "978-0-7432-7356-5")
 92    book2 = LibraryBook("To Kill a Mockingbird", "Harper Lee", "978-0-06-112008-4")
 93    book3 = LibraryBook("1984", "George Orwell", "978-0-452-28423-4")
 94    
 95    print("=== Library System Demo ===")
 96    print("Initial book status:")
 97    print(book1.get_book_status())
 98    print(book2.get_book_status())
 99    print(book3.get_book_status())
100    print()
101    
102    # Simulate borrowing
103    print("=== Borrowing Books ===")
104    book1.borrow_book("Alice Johnson")
105    book2.borrow_book("Bob Smith")
106    book1.borrow_book("Carol Davis")  # Should fail - already borrowed
107    print()
108    
109    # Check current status
110    print("=== Current Status ===")
111    print(book1.get_book_status())
112    print(book2.get_book_status())
113    print(book3.get_book_status())
114    print()
115    
116    # Return books and borrow again
117    print("=== Returns and New Borrowing ===")
118    book1.return_book()
119    book1.borrow_book("David Wilson")
120    book1.return_book()
121    book1.borrow_book("Eve Adams")
122    print()
123    
124    # Show popularity and history
125    print("=== Book Analytics ===")
126    print(f"Book 1 popularity: {book1.get_popularity_level()}")
127    print(f"Book 2 popularity: {book2.get_popularity_level()}")
128    print(f"Book 3 popularity: {book3.get_popularity_level()}")
129    print()
130    
131    print("Book 1 borrowing history:")
132    for entry in book1.get_borrow_history():
133        print(f"  {entry}")
134
135# Run the demo
136if __name__ == "__main__":
137    demo_library_system()

What to Notice:

Details
  • Multiple related attributes: is_available, borrowed_by, borrow_count work together
  • State consistency: Methods ensure logical consistency between attributes
  • History tracking: borrow_history maintains a record of all transactions
  • Business logic: Methods enforce library rules (can’t borrow if already borrowed)
Details
  • Precondition checking: Methods verify state before performing actions
  • Return values: Boolean returns indicate success/failure of operations
  • User feedback: Print statements provide immediate feedback
  • Graceful failure: Invalid operations don’t crash, they report errors
Details
  • Derived information: get_popularity_level() calculates from borrow_count
  • Status reporting: get_book_status() combines multiple attributes
  • Data protection: get_borrow_history().copy() prevents external changes
  • Business intelligence: Methods provide insights into book usage patterns

Reading Practice Tips

After studying these Python class examples:

  1. Follow object creation: Trace how __init__ sets up initial object state
  2. Understand self: Notice how self refers to the current object in every method
  3. Track attribute changes: Follow how methods modify object attributes over time
  4. Compare objects: See how multiple instances maintain independent state
  5. Practice method tracing: Follow the flow of method calls and return values

These Python patterns show how object-oriented programming works in Python’s dynamic, readable style. Understanding classes and methods will help you read more complex Python code with confidence.