Inheritance, Special Methods and Dataclasses
Intuition
Rectangles, squares and circles are all shapes: they all have an area and can describe
themselves. Inheritance lets you write the shared parts once in a base class and only the
differences in each subclass. A square is a rectangle with equal sides, so Square can inherit
almost everything from Rectangle.
Precise explanation
class Shape:
name = "shape"
def area(self):
raise NotImplementedError("subclasses must implement area")
def describe(self): # shared code, uses self.area()
return f"{self.name} with area {self.area():.2f}"
class Rectangle(Shape): # Rectangle inherits from Shape
name = "rectangle"
def __init__(self, width, height):
self.width, self.height = width, height
def area(self): # overrides Shape.area
return self.width * self.height
class Square(Rectangle):
name = "square"
def __init__(self, side):
super().__init__(side, side) # reuse the parent's initialiser
- Method lookup goes object → class → parent → ... (
Square→Rectangle→Shape). isinstance(Square(2), Rectangle)isTrue. Code that callsshape.area()works for any subclass — this is polymorphism.- Special ("dunder") methods customise operators:
__eq__for==,__lt__for<(which makessortedwork),__repr__for display,__add__for+. @dataclass(fromdataclasses) writes__init__,__repr__and__eq__from annotated fields:
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
Point(1, 2) == Point(1, 2) # True; repr: Point(x=1, y=2)
x: float is a type annotation: documentation for readers and tools; Python does not convert
or check the value. (Pydantic, in FA-10, does check.)
Worked example
[Square(2), Circle(1)] → describe() gives "square with area 4.00" and
"circle with area 3.14"; sorted with __lt__ comparing areas puts the circle first.
Common mistakes
- Forgetting
super().__init__(...), so parent attributes are never set. - Defining
__eq__but comparing different types; returnNotImplementedfor unknown types. - Deep inheritance trees: prefer a shallow hierarchy and small classes.
Why this matters
Deep-learning frameworks are built on inheritance (every layer subclasses a base Module), and
FastAPI request models subclass Pydantic's BaseModel.
References
- The Python Tutorial: Classes — Python Software Foundation (
S046) - dataclasses — Data Classes — Python Software Foundation (
S057)