1. Abstract Base Classes (ABC)
An Abstract Base Class (ABC) allows you to define a set of methods that subclasses must implement. This enforces a strict interface or API contract in your code. We use the built-inabc module, ABC subclass, and @abstractmethod decorator:
2. Classes are Objects (Metaclasses)
In Python, everything is an object, including classes themselves. When you write aclass statement, Python executes it and creates a class object in memory.
By default, all classes are instances of the metaclass type:
Dynamic Class Creation with type()
Because classes are objects, you can create them dynamically using the three-argument form of the built-in type(name, bases, dict) constructor:
3. Special Attributes: __dict__ and __annotations__
Python class objects maintain internal dictionaries to manage namespaces and metadata:
__dict__
The namespace dictionary containing all local attributes, functions, and methods defined directly on the object/class.
__annotations__
A dictionary that stores the type hints defined on the class attributes or parameters. This dictionary is crucial for libraries performing runtime type checks.
4. Dunder Methods (Magic Methods)
Dunder (Double-Underscore) methods allow you to hook into Python’s built-in behaviors:__new__: The static creator method responsible for allocating memory and returning a new instance of a class. It runs before__init__.__init__: The initializer method that configures the fields on the instance returned by__new__.__call__: Allows instances of your class to be called like functions.__repr__/__str__: Control how your object is converted to a string.
5. Class Creation Stages
When a class definition is executed, Python goes through distinct stages to build the class object using its metaclass: To intercept this creation pipeline, you define a custom metaclass subclassingtype.
6. Real-World Framework Implementations
Advanced OOP mechanics are the backbone of modern Python frameworks:SQLAlchemy (Declarative Bases)
SQLAlchemy uses metaclasses to inspect class attributes and map them automatically to relational database columns:- When you define a class inheriting from
DeclarativeBase, SQLAlchemy’s metaclass intercepts the class definition. - It parses class attributes (like
id = Column(Integer)) and reads the class name to register database tables. - It maps the class attributes to query descriptors, meaning when you assign
user.name = "Rahul", it tracks database updates dynamically.
FastAPI / Pydantic (BaseModel)
Pydantic uses metaclasses and annotations to perform automatic serialization and data validation:- When a class inheriting from Pydantic’s
BaseModelis created, Pydantic’s metaclass reads__annotations__at runtime. - It builds validator functions based on types (e.g.
age: intgenerates an integer parser). - FastAPI intercepts HTTP requests, passes them to Pydantic schemas, and raises detailed parsing errors if values don’t match, all before your endpoint function runs.
Practice & Exercises
To reinforce what you’ve learned in this section (Abstract Classes, Metaclasses, and Dunder hooks), practice with these interactive notebooks:Follow-Along Practice
Practice creating Abstract classes, hook new, dynamically create classes, and inspect annotations.💻 VS Code | 🚀 Colab | 📥 Download
Practice Exercises
Test your advanced OOP understanding with custom exercises on interface enforcement and metaclass inspectors.💻 VS Code | 🚀 Colab | 📥 Download
What’s next?
Learn about how to validate your data using Type Hints, Dataclasses, and Pydantic!Introduction to Pydantic
Learn runtime type validation and Pydantic models