⚙️
Intermediate
class · __init__ · Methods · Properties · dataclass
Week 7 — OOP Part 1: Classes & Instances
Model real-world entities with classes. Learn to define attributes in __init__, write instance methods, use properties for validation, and simplify data classes with @dataclass.
OOPclassinstance__init__propertydataclass
Duration
⏱ 3 hours
Level
📊 Intermediate
Prerequisite
🎯 Basic Week 9
OUTCOME
Model a bank account with deposit, withdraw, and balance validation
What you'll learn
- 1Define a class with __init__ and instance attributes
- 2Write instance methods that operate on self
- 3Use @property for computed attributes and validation
- 4Distinguish class attributes from instance attributes
- 5Create simple data containers with @dataclass
1. Classes and Instances
python
class Dog:
species = "Canis lupus familiaris" # class attribute
def __init__(self, name, age):
self.name = name # instance attribute
self.age = age
def bark(self):
return f"{self.name} says: Woof!"
def __repr__(self):
return f"Dog(name={self.name!r}, age={self.age})"
fido = Dog("Fido", 3)
print(fido.bark())
print(repr(fido))
print(Dog.species)2. Properties
python
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self._balance = balance # private by convention
@property
def balance(self):
return self._balance
@balance.setter
def balance(self, value):
if value < 0:
raise ValueError("Balance cannot be negative")
self._balance = value
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount > self.balance:
raise ValueError("Insufficient funds")
self.balance -= amount
acct = BankAccount("Alice", 1000)
acct.deposit(500)
acct.withdraw(200)
print(acct.balance) # 13003. @dataclass
python
from dataclasses import dataclass, field
@dataclass
class Point:
x: float
y: float
def distance_to(self, other):
return ((self.x-other.x)**2 + (self.y-other.y)**2)**0.5
p1 = Point(0, 0)
p2 = Point(3, 4)
print(p1.distance_to(p2)) # 5.0
print(p1) # Point(x=0, y=0)4. Common Mistakes
- Forgetting self as the first parameter of instance methods.
- Using a mutable default (list/dict) in __init__ signature — use field(default_factory=list) with dataclass.
- Confusing class attributes (shared by all instances) with instance attributes (unique per instance).
💻 Examples
Run these examples and check the output yourself.
01_bank_account.py— BankAccount with full transaction history
CODE
class BankAccount:
def __init__(self, owner):
self.owner = owner
self._balance = 0.0
self._history = []
@property
def balance(self): return self._balance
def deposit(self, amount):
if amount <= 0: raise ValueError("Amount must be positive")
self._balance += amount
self._history.append(f"+{amount:.2f}")
def withdraw(self, amount):
if amount > self._balance: raise ValueError("Insufficient funds")
self._balance -= amount
self._history.append(f"-{amount:.2f}")
def statement(self):
print(f"Account: {self.owner}")
for tx in self._history:
print(f" {tx}")
print(f" Balance: {self._balance:.2f}")
acct = BankAccount("Alice")
acct.deposit(1000)
acct.deposit(500)
acct.withdraw(200)
acct.statement()
▶ Output
Account: Alice
+1000.00
+500.00
-200.00
Balance: 1300.00📝 Exercises
Try them yourself first, then open the solution to compare.
Exercise 1
Student class
Goal: Model a student with name, scores list, and a computed grade property.
Requirements
- __init__(name)
- add_score(score) method
- average property (float)
- grade property: A/B/C/D/F based on average
- __repr__ returning Student(name, avg=XX.X, grade=X)
▶Toggle solution
SOLUTION
class Student:
def __init__(self, name):
self.name = name
self._scores = []
def add_score(self, score):
self._scores.append(score)
@property
def average(self):
return sum(self._scores) / len(self._scores) if self._scores else 0.0
@property
def grade(self):
a = self.average
if a >= 90: return "A"
if a >= 80: return "B"
if a >= 70: return "C"
if a >= 60: return "D"
return "F"
def __repr__(self):
return f"Student({self.name!r}, avg={self.average:.1f}, grade={self.grade})"
s = Student("Alice")
for sc in [90, 85, 92]: s.add_score(sc)
print(s)
▶ Output
Student('Alice', avg=89.0, grade=BExample code / lecture materials
All lecture materials and example code are openly available on GitHub.
View on GitHub ↗