Python Classes & OOP
Bundle data and behavior together into reusable objects.
Defining a class
Python
class Dog:
'''Represents a dog.'''
species = "Canis lupus familiaris" # class attribute (shared)
def __init__(self, name, age):
self.name = name # instance attributes
self.age = age
def bark(self):
return f"{self.name} says: Woof!"
def __str__(self):
return f"Dog({self.name}, {self.age})"
# Create instances
rex = Dog("Rex", 3)
buddy = Dog("Buddy", 5)
print(rex.bark()) # Rex says: Woof!
print(rex) # Dog(Rex, 3) — __str__
print(rex.species) # Canis lupus familiaris
Inheritance
Python
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "Some sound"
class Cat(Animal): # Cat inherits from Animal
def speak(self): # override speak
return f"{self.name} says: Meow!"
class Dog(Animal):
def speak(self):
return f"{self.name} says: Woof!"
animals = [Cat("Kitty"), Dog("Rex")]
for a in animals:
print(a.speak()) # polymorphism!
@property — controlled attribute access
Python
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("Radius must be non-negative")
self._radius = value
@property
def area(self):
import math
return math.pi * self._radius ** 2
c = Circle(5)
print(c.area) # 78.53... — computed on access
c.radius = -1 # ❌ ValueError
@classmethod and @staticmethod
Python
class Counter:
count = 0
def __init__(self):
Counter.count += 1
@classmethod
def get_count(cls): # receives class, not instance
return cls.count
@staticmethod
def is_positive(n): # no class or instance reference
return n > 0
Counter(); Counter(); Counter()
Counter.get_count() # 3
Counter.is_positive(5) # True