Classes & Objects
Object-Oriented Programming (OOP) lets you model real-world things as objects with attributes (data) and methods (behavior). A class is a blueprint, and objects are instances created from that blueprint. Almost everything in Python is an object - strings, lists, functions - and now you'll learn to create your own!
Class Basics
Define a class with the class keyword. Classes are blueprints for creating
objects. When you create an object from a class, you get an instance with
its own data. Each instance is independent - changing one doesn't affect others.
Click Run to execute your code
class ClassName: - Define a class (PascalCase naming)obj = ClassName() - Create an instance (object)type(obj) - Check object's typeisinstance(obj, Class) - Check if object is instance of classRemember: A class is a blueprint; objects are instances built from it.
The __init__ Method
The __init__ method (constructor) initializes new objects. It runs automatically
when you create an instance. The first parameter is always self, which refers to
the instance being created. Use it to set up instance attributes with initial values.
Click Run to execute your code
-
self is the instance being created or operated on- It's passed automatically - you don't provide it when calling
- Use
self.attribute = value to set instance attributes-
__init__ doesn't return anything (always returns None)Note:
self is just a convention - you could use any name, but don't!
Instance vs Class Attributes
Instance attributes are unique to each object - set them in __init__
using self.attr = value. Class attributes are shared by all instances -
define them directly in the class body. Be careful: assigning to an instance can shadow class attributes!
Click Run to execute your code
Never use mutable defaults (lists, dicts) as class attributes! They're shared by all instances.
class Bad: items = [] - All instances share the same list!class Good: def __init__(self): self.items = [] - Each gets its own list.
Working with Objects
Objects are reference types - variables hold references to objects, not the objects themselves.
This means passing objects to functions passes the reference, allowing modification of the original.
Use is to check identity (same object) and == for equality (same value).
Click Run to execute your code
obj.attr - Access attributeobj.attr = value - Set attributehasattr(obj, 'attr') - Check if attribute existsgetattr(obj, 'attr', default) - Get attribute with defaultobj.__dict__ - Dictionary of instance attributesid(obj) - Unique object identifier (memory address)
Common Mistakes
1. Forgetting self in __init__
# Wrong - name becomes local variable, not attribute!
class Person:
def __init__(self, name):
name = name # Useless! Doesn't save to instance
# Correct - use self to save to instance
class Person:
def __init__(self, name):
self.name = name # Now it's an instance attribute
2. Mutable default in class body
# Wrong - all instances share the same list!
class Team:
members = [] # Class attribute - shared!
t1 = Team()
t2 = Team()
t1.members.append("Alice")
print(t2.members) # ['Alice'] - OOPS!
# Correct - create list in __init__
class Team:
def __init__(self):
self.members = [] # Instance attribute - unique
3. Confusing class name with variable
# Wrong - calling class like function without saving result
class User:
def __init__(self, name):
self.name = name
User("Alice") # Creates object but throws it away!
# Correct - save the instance to a variable
user = User("Alice")
print(user.name) # Now we can use it
4. Shadowing class attributes
class Counter:
count = 0 # Class attribute
c1 = Counter()
c2 = Counter()
# Wrong - this creates an INSTANCE attribute on c1!
c1.count = 5
print(Counter.count) # Still 0!
print(c2.count) # Still 0!
# Correct - modify class attribute through class name
Counter.count = 5
print(c1.count) # 5 (reads class attr)
print(c2.count) # 5
5. Returning from __init__
# Wrong - __init__ should not return anything!
class Builder:
def __init__(self, name):
self.name = name
return self # Error or ignored!
# Correct - just set attributes, no return
class Builder:
def __init__(self, name):
self.name = name
# Implicitly returns None
Exercise: Bank Account Class
Task: Create a BankAccount class with proper initialization.
Requirements:
- Initialize with owner name and optional starting balance (default 0)
- Add a class attribute to track total accounts created
- Validate that balance is not negative in __init__
- Create a method to display account info
Click Run to execute your code
Show Solution
class BankAccount:
"""A simple bank account class."""
# Class attribute - tracks all accounts
total_accounts = 0
def __init__(self, owner, balance=0):
"""Initialize account with owner and optional balance."""
if not owner:
raise ValueError("Owner name is required")
if balance < 0:
raise ValueError("Initial balance cannot be negative")
self.owner = owner
self.balance = balance
self.account_number = BankAccount.total_accounts + 1000
# Increment class counter
BankAccount.total_accounts += 1
def display(self):
"""Display account information."""
return f"Account #{self.account_number}: {self.owner}, Balance: ${self.balance:.2f}"
# Test the class
acc1 = BankAccount("Alice", 1000)
acc2 = BankAccount("Bob", 500)
acc3 = BankAccount("Charlie") # Uses default balance
print("=== Bank Accounts ===")
print(acc1.display())
print(acc2.display())
print(acc3.display())
print(f"\nTotal accounts created: {BankAccount.total_accounts}")
# Test validation
try:
bad = BankAccount("", 100)
except ValueError as e:
print(f"\nValidation error: {e}")
Summary
- class:
class ClassName:defines a blueprint for objects - Object: An instance created from a class:
obj = ClassName() - __init__: Constructor method that initializes new instances
- self: First parameter, refers to the instance being created/used
- Instance attributes: Unique per object, set with
self.attr - Class attributes: Shared by all instances, defined in class body
- Identity:
ischecks same object,==checks equality - Avoid: Mutable class attributes, forgetting self, returning from __init__
What's Next?
Now that you can create classes with attributes, it's time to add behavior! Next, we'll learn about methods - functions that belong to classes. You'll learn about instance methods, class methods, static methods, and how to make your objects do things!
Enjoying these tutorials?