Classes & Objects in Python

Module 3 • Session 22 • Creating Blueprints, Instantiating Objects & Method Binding

class-keyword object-instantiation self-parameter instance-methods object-introspection

At the core of Object-Oriented Programming in Python lies the concept of Classes and Objects. A class acts as a customized user-defined data structure, functioning as a blueprint or template from which individual object instances are instantiated.

1. Anatomy of a Python Class

Classes are defined using the class keyword followed by the class name, conventionally written in PascalCase (e.g., SmartPhone). Inside a class, we define state attributes and function behaviors called methods.

# Defining a minimal class definition class Car: """Blueprint representing a automotive vehicle.""" pass # Checking type and object creation print(type(Car)) # <class 'type'>
Key Insight: In Python, class definitions are executable statements. When executed, Python creates a new type object in memory assigned to the class identifier name.

2. Instantiating Objects

To create an instance of a class (an object), call the class name as if it were a function. This process is called instantiation. Every object instantiated from a class gains its own unique identity and memory address.

class Laptop: brand = "Generic" # Instantiating two distinct object instances laptop1 = Laptop() laptop2 = Laptop() print(laptop1) # Output: <__main__.Laptop object at 0x7f9a8c1b20> print(laptop2) # Output: <__main__.Laptop object at 0x7f9a8c1c40> # Verifying identity uniqueness print(laptop1 is laptop2) # False

3. Demystifying the `self` Parameter

Every instance method inside a class must accept self as its first positional parameter. When calling an instance method using dot-notation, Python automatically passes the underlying object as the first argument.

class Device: def turn_on(self): print(f"Device at memory address {hex(id(self))} is now powered ON.") dev = Device() # Explicit call style vs standard syntactic sugar: dev.turn_on() # Syntactic sugar -> passes 'dev' automatically Device.turn_on(dev) # Under the hood execution!

4. Defining Instance Attributes & Methods

Methods can access and modify the specific state of the invoking object via self. Attributes bound directly to self belong exclusively to that specific instance.

Concept Syntactic Signature Description & Behavior
Class Definition class ClassName: Creates a template in memory defining shared structure.
Instantiation obj = ClassName() Allocates a fresh instance in memory.
Self Keyword def method(self): Reference pointer bound to the current calling instance.
Attribute Binding self.attribute_name = value Creates an instance variable tied directly to an object instance.

Detailed Example: Building a Bank Account Model

The example below demonstrates defining methods, modifying state variables across operations, and handling multiple object instances:

class Account: def set_account_details(self, holder_name, initial_balance=0.0): self.holder_name = holder_name self.balance = float(initial_balance) def deposit(self, amount): if amount > 0: self.balance += amount print(f"[{self.holder_name}] Deposited ${amount:.2f}. New Balance: ${self.balance:.2f}") else: print("Deposit amount must be positive.") def withdraw(self, amount): if 0 < amount <= self.balance: self.balance -= amount print(f"[{self.holder_name}] Withdrew ${amount:.2f}. Remaining Balance: ${self.balance:.2f}") else: print(f"[{self.holder_name}] Transaction declined: Insufficient funds.") # Object Instantiation & Setup acc_a = Account() acc_a.set_account_details("Alice", 1000.00) acc_b = Account() acc_b.set_account_details("Bob", 250.00) # Operations acc_a.deposit(500) acc_b.withdraw(300) # Insufficient funds warning acc_a.withdraw(200)

5. Dynamic Attribute Assignment & Introspection

Unlike statically typed languages like Java or C++, Python allows attaching new attributes to specific object instances dynamically at runtime. You can inspect an object's instance dictionary using the built-in __dict__ attribute or functions like hasattr(), getattr(), and setattr().

class Person: pass p1 = Person() p1.name = "John Doe" # Dynamic attribute creation! p1.age = 30 print(p1.__dict__) # {'name': 'John Doe', 'age': 30} # Built-in attribute reflection methods if hasattr(p1, "name"): print("Name retrieved:", getattr(p1, "name")) setattr(p1, "location", "New York") print("Updated dict:", p1.__dict__)
Warning: While dynamic attribute binding offers flexibility, overuse can lead to unmaintainable code and runtime errors if code relies on attributes that may not exist across all instance objects.

6. Comprehensive End-to-End Example: E-Commerce Cart System

Let's consolidate these core concepts into a cohesive model representing an interactive e-commerce shopping cart system.

class ShoppingCart: def initialize_cart(self, customer_name): self.customer_name = customer_name self.items = [] def add_item(self, item_name, price, quantity=1): item = {"item": item_name, "price": price, "qty": quantity} self.items.append(item) print(f"Added {quantity}x '{item_name}' to {self.customer_name}'s cart.") def calculate_total(self): total = sum(item["price"] * item["qty"] for item in self.items) return total def print_receipt(self): print(f"\n--- RECEIPT FOR {self.customer_name.upper()} ---") for idx, item in enumerate(self.items, 1): subtotal = item['price'] * item['qty'] print(f"{idx}. {item['item']} (x{item['qty']}) - ${subtotal:.2f}") print(f"TOTAL: ${self.calculate_total():.2f}\n") # Execution cart = ShoppingCart() cart.initialize_cart("Sarah Connor") cart.add_item("Mechanical Keyboard", 120.50, 1) cart.add_item("Wireless Mouse", 45.00, 2) cart.print_receipt()

🏋️ Try It Yourself: Interactive Exercises

Challenge 1: Student Grade Manager

Design a `Student` class with methods `setup(name)`, `add_grade(score)`, and `get_average()`. Instantiate two student objects and calculate their averages.

Challenge 2: Bank Account Transfer Mechanism

Extend the `Account` class with a `transfer(target_account, amount)` method that moves money between two distinct object instances.

Challenge 3: Dynamic Attribute Validator

Write a script using `getattr()` and `hasattr()` to safely read attributes from an object without triggering `AttributeError` exceptions.

⚡ Interactive Sandbox (Classes & Objects in Python)
Console Output:
Click "Run Code" above to execute scripts...

📝 Knowledge Check Quiz

1. What role does the `self` parameter serve inside Python instance methods?
2. What happens when you instantiate a class (e.g., `obj = MyClass()`)?
3. How can you inspect all instance attributes dynamically bound to an object instance?
Advertisement
Horizontal Ad Banner Slot (728x90 / Responsive)