class
The class keyword in Python is used to define a new class. Classes serve as blueprints for creating objects that bundle data (attributes) and behavior (methods) together.
Syntax
class ClassName:
# class body
pass
# With inheritance
class ClassName(BaseClass):
# class body
pass
# With keyword arguments
class ClassName(param="default"):
# class body
pass
How It Works
When Python encounters a class statement, it:
- Creates a new namespace (local scope)
- Executes the class body within that namespace
- Binds the resulting class object to the class name
# Simple class definition
class Dog:
"""A simple Dog class."""
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
return f"{self.name} says woof!"
# Creating an instance
my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.name)
# Buddy
print(my_dog.bark())
# Buddy says woof!
The init Method
The __init__ method is called when an instance is created. It’s not a constructor — __new__ handles that — but an initializer that sets up the object:
class Person:
def __init__(self, name, age):
# These become instance attributes
self.name = name
self.age = age
person = Person("Alice", 30)
print(person.name, person.age)
# Alice 30
Class vs Instance Attributes
Class attributes are shared across all instances, while instance attributes are unique to each object:
class Dog:
# Class attribute - same for all dogs
species = "Canis familiaris"
def __init__(self, name):
# Instance attribute - unique to each dog
self.name = name
dog1 = Dog("Buddy")
dog2 = Dog("Max")
print(dog1.species) # Class attribute
# Canis familiaris
print(dog2.species) # Same class attribute
# Canis familiaris
print(dog1.name) # Instance attribute
# Buddy
print(dog2.name) # Different instance attribute
# Max
# Modifying class attribute affects all instances
Dog.species = "Canis lupus"
print(dog1.species, dog2.species)
# Canis lupus Canis lupus
Methods
Methods are functions defined inside a class. The first parameter is always self, which refers to the instance:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
def __str__(self):
return f"Rectangle({self.width}x{self.height})"
rect = Rectangle(5, 3)
print(rect.area())
# 15
print(rect.perimeter())
# 16
print(rect)
# Rectangle(5x3)
Inheritance
Classes can inherit from other classes, gaining their methods and attributes:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("Subclass must implement speak()")
class Cat(Animal):
def speak(self):
return f"{self.name} says meow!"
class Dog(Animal):
def speak(self):
return f"{self.name} says woof!"
cat = Cat("Whiskers")
dog = Dog("Buddy")
print(cat.speak())
# Whiskers says meow!
print(dog.speak())
# Buddy says woof!
Multiple Inheritance
Python supports multiple inheritance:
class Flyer:
def fly(self):
return "Flying high!"
class Swimmer:
def swim(self):
return "Swimming deep!"
class Duck(Flyer, Swimmer):
pass
duck = Duck()
print(duck.fly())
# Flying high!
print(duck.swim())
# Swimming deep!
Method Types
Instance methods
class MyClass:
def instance_method(self):
return "Instance method called"
Class methods
class MyClass:
@classmethod
def class_method(cls):
return "Class method called"
Static methods
class MyClass:
@staticmethod
def static_method():
return "Static method called"
Class Variables and Mutable Defaults
A common pitfall — never use mutable objects as default class attributes:
# BAD - all instances share the same list
class BadExample:
items = [] # Shared across all instances!
def add(self, item):
self.items.append(item)
# GOOD - create new list per instance
class GoodExample:
def __init__(self):
self.items = [] # New list per instance
def add(self, item):
self.items.append(item)
Dataclasses (Python 3.7+)
For simple data containers, Python’s dataclasses reduce boilerplate::
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
def distance_from_origin(self):
return (self.x**2 + self.y**2) ** 0.5
point = Point(3, 4)
print(point.distance_from_origin())
# 5.0
See Also
- dataclasses module — decorator for automatic init, repr, etc.
- collections module — many more collection types - namedtple, Counter, Deque, etc.
- enum module — for creating enumerated constants.