Classes and Inheritance
Defining a class
Section titled “Defining a class”The class keyword defines a new type.
The body contains methods (functions defined inside a class) and optionally class attributes (shared by all instances).
class Dog: species: str = "Canis lupus familiaris" # class attribute
def __init__(self, name: str, age: int) -> None: self.name = name # instance attribute self.age = age # instance attribute
def bark(self) -> str: return f"{self.name} says woof!"self — the instance reference
Section titled “self — the instance reference”Every instance method receives the instance as its first argument, conventionally named self.
Python passes it automatically; you never pass it yourself:
rex = Dog("Rex", 3)rex.bark() # Python calls Dog.bark(rex) under the hoodself is not a keyword — you could name it anything — but self is the universal Python convention and deviating from it confuses every reader and every tool.
Instance vs class attributes
Section titled “Instance vs class attributes”| Instance attribute | Class attribute | |
|---|---|---|
| Where defined | Inside __init__, on self | Directly in the class body |
| Where stored | On each individual object | On the class itself |
| Access | obj.attr | ClassName.attr or obj.attr (fallback) |
Mutating a class attribute through an instance creates a shadow instance attribute and does not change the class attribute for other instances. Use class attributes only for constants or shared state that truly belongs to the class.
Inheritance and super()
Section titled “Inheritance and super()”A subclass inherits all methods from its parent.
Use super() to call the parent’s method — most commonly super().__init__() to initialise the parent’s state.
class Animal: def __init__(self, name: str, sound: str) -> None: self.name = name self.sound = sound
def speak(self) -> str: return f"{self.name} says {self.sound}"
class Dog(Animal): def __init__(self, name: str) -> None: super().__init__(name, "woof") # delegate to Animal.__init__
def fetch(self, item: str) -> str: return f"{self.name} fetches the {item}!"super() without arguments works in Python 3 — no need to pass the class or instance explicitly.
Full runnable demo
Section titled “Full runnable demo”class Animal: kingdom: str = "Animalia"
def __init__(self, name: str, sound: str) -> None: self.name = name self.sound = sound
def speak(self) -> str: return f"{self.name} says {self.sound}"
class Dog(Animal): def __init__(self, name: str) -> None: super().__init__(name, "woof")
def fetch(self, item: str) -> str: return f"{self.name} fetches the {item}!"
dog = Dog("Rex")print(dog.speak())print(dog.fetch("ball"))print(Dog.kingdom)print(isinstance(dog, Animal))Loading Python runtime (first run only)…