Module 01 - Object-Oriented Programming
Reading time: ~10 minutes | Level: Intermediate
Here is a question most Python developers answer wrong:
class A:
data = []
a = A()
b = A()
a.data.append(1)
print(b.data) # What prints?
The answer is [1].
Both instances share the same list. Not because of a bug. Because of how Python resolves attribute lookup - and most developers have never thought about it at this level.
This module exists to close that gap.
What This Module Covers
Object-oriented programming in Python is not about memorising syntax. It is about understanding the object model that drives every framework, library, and production system you will ever work with.
Django models, SQLAlchemy ORM, FastAPI request objects, PyTorch nn.Module, dataclasses - all of these are Python OOP at work. Understanding them deeply means understanding what is underneath them.
By the end of this module, you will be able to:
- Design classes that behave like built-in Python types
- Explain exactly how Python resolves attributes across inheritance hierarchies
- Know when to use inheritance, when to use composition, and why it matters
- Write production-quality code using dataclasses and abstract base classes
- Apply SOLID principles in real Python - not just define them
- Recognise and implement the patterns that appear in every major Python framework
Module Topics
01 - Classes and Objects
Not a beginner introduction. An engineering-level breakdown of what a class actually is in Python's object model.
You will understand the difference between class and instance, how the namespace lookup chain works, class vs instance attributes, the class body execution model, and why the opening puzzle behaves the way it does.
Key concepts: type, __dict__, namespace chain, class body, instance creation, attribute resolution
02 - __init__ and Object Construction
__init__ is not a constructor. __new__ is the constructor. __init__ is the initialiser.
You will understand the two-phase object creation process, when you need __new__, how __init__ sets instance state, default mutable argument traps, and how super().__init__() chains correctly.
Key concepts: __new__, __init__, super(), MRO in initialisation, mutable defaults, __post_init__
03 - Dunder Methods
Dunder methods are Python's protocol system. They are how your objects plug into the language itself.
You will implement comparison, arithmetic, container behaviour, context managers, and callable objects - all through the dunder protocol that every built-in type uses internally.
Key concepts: __eq__, __lt__, __add__, __len__, __getitem__, __enter__, __exit__, __call__
04 - Representation and String Methods
str(), repr(), format() - three different protocols, three different use cases.
You will understand when Python calls each, how __repr__ should always produce a valid constructor call, why __str__ is for humans and __repr__ is for engineers, and how __format__ powers f-string format specs on custom objects.
Key concepts: __repr__, __str__, __format__, !r vs !s in f-strings, pprint, logging
05 - Encapsulation and Data Hiding
Python does not enforce private access. It relies on convention and property descriptors.
You will understand single underscore convention, name mangling with double underscore, @property for controlled access, @setter for validation, and when descriptors replace properties entirely.
Key concepts: _private, __mangled, @property, @setter, @deleter, descriptors, __slots__
06 - Inheritance
Inheritance in Python is more powerful and more dangerous than in most languages.
You will understand single and multiple inheritance, method resolution, super() in cooperative inheritance, the fragile base class problem, and when inheritance creates coupling you will regret.
Key concepts: super(), method override, cooperative inheritance, isinstance, issubclass, fragile base class
07 - Composition vs Inheritance
"Favour composition over inheritance" is not a rule. It is a trade-off with specific conditions.
You will understand when inheritance is correct (true is-a relationships), when composition is better (has-a relationships), how to refactor inheritance-heavy code to composition, and what dependency injection looks like in Python.
Key concepts: is-a vs has-a, delegation, mixins, dependency injection, protocol classes
08 - MRO Explained
Python's Method Resolution Order determines which method runs when multiple inheritance is involved.
You will understand the C3 linearisation algorithm, how super() traverses the MRO, diamond inheritance, and how Django, Flask, and other frameworks use mixins that depend on MRO correctness.
Key concepts: C3 linearisation, __mro__, diamond problem, mixin patterns, super() chain
09 - Abstract Base Classes
ABCs enforce interface contracts at class definition time - before any instance is created.
You will implement ABCs with abc.ABC and @abstractmethod, understand virtual subclasses via register(), and see how Python's own collections ABCs (Sequence, Mapping, Iterable) power duck typing at scale.
Key concepts: abc.ABC, @abstractmethod, register(), collections.abc, structural subtyping
10 - Dataclasses
@dataclass is not syntactic sugar. It is a code generation tool that produces __init__, __repr__, __eq__, and more from field declarations.
You will understand field(), default_factory, frozen=True for immutability, __post_init__, inheritance with dataclasses, and how they compare to NamedTuple and attrs.
Key concepts: @dataclass, field(), default_factory, frozen, __post_init__, ClassVar, InitVar
11 - SOLID in Python
SOLID principles are not Java concepts. They apply directly to Python - often more elegantly.
You will apply each principle with Python-specific examples: SRP via single-responsibility modules, OCP via protocol classes, LSP via correct subtyping, ISP via small focused ABCs, DIP via dependency injection.
Key concepts: SRP, OCP, LSP, ISP, DIP, protocol classes, dependency injection, typing.Protocol
12 - Design Patterns Basics
Patterns are solutions to recurring design problems. Python's dynamic nature makes several GoF patterns trivial or unnecessary - and creates entirely new ones.
You will implement: Singleton (and why it is usually wrong), Factory, Strategy, Observer, and Decorator - all with idiomatic Python, not Java-translated code.
Key concepts: Singleton, Factory, Strategy, Observer, Decorator pattern vs decorator syntax, registry pattern
Module Projects
| Project | Core Skills |
|---|---|
| Inventory Management System | Classes, encapsulation, inheritance, __repr__ |
| Plugin Architecture | ABCs, factory pattern, dynamic loading |
| Dataclass-powered Config System | Dataclasses, validation, frozen instances |
| Mini ORM | Descriptors, metaclasses, MRO, class attributes |
Prerequisites
- Python Foundation course complete (or equivalent depth)
- Comfortable with functions, loops, and basic data structures
- Understand that functions are objects in Python
How to Use This Module
Lessons build on each other. Read them in order.
__init__ (02) assumes you understand class/instance from lesson 01.
Inheritance (06) assumes you understand __init__ and dunders.
MRO (08) assumes you understand inheritance.
SOLID (11) assumes you understand all of the above.
After every lesson: open your editor and implement the concepts. Copy-pasting examples does not build understanding. Writing them from memory does.
The Engineering Standard
This module is written for engineers building production systems.
Every concept is connected to a real framework, a real failure mode, or a real design decision. By the end, you will not just understand Python OOP.
You will understand why SQLAlchemy models work the way they do, why Django's class-based views use MRO the way they do, and why PyTorch's nn.Module is designed the way it is.
That understanding is not academic. It is the difference between using a framework and mastering it.
