Python26 min read
Python Metaclasses
Understand what metaclasses are, why they exist, and how they can enforce rules or inject behavior at class creation time (with safer alternatives).
David Miller
July 24, 2025
4.5k125
Metaclasses are an advanced topic. You should learn them only after you are comfortable with:
- classes
- inheritance
- decorators
- class methods and static methods
But once you understand them, you will see how frameworks like Django do powerful things automatically.
## The core idea
- An object is created by a class.
- A class is created by a **metaclass**.
In Python, most classes are created by the built-in metaclass named `type`.
```python
class MyClass:
pass
print(type(MyClass)) # <class 'type'>
```
So yes, Python’s `type` is the “class that creates classes”.
## When metaclasses are useful
Metaclasses are useful when you want to control class creation, for example:
- enforce that a class must contain specific methods
- automatically add attributes/methods to every class
- register classes (plugin systems)
- build ORM-like behavior
## Example 1: Inject a method into every class
```python
class Meta(type):
def __new__(cls, name, bases, attrs):
# add a greet method to every class built with this metaclass
def greet(self):
print(f"Hi, I am an instance of {name}")
attrs["greet"] = greet
return super().__new__(cls, name, bases, attrs)
class User(metaclass=Meta):
pass
u = User()
u.greet()
```
Expected output:
```
Hi, I am an instance of User
```
## Example 2: Enforce a rule (validation metaclass)
Imagine you want every repository class to have a `save()` method.
```python
class ValidationMeta(type):
def __new__(cls, name, bases, attrs):
if name != "BaseRepo" and "save" not in attrs:
raise TypeError(f"{name} must define a save() method")
return super().__new__(cls, name, bases, attrs)
class BaseRepo(metaclass=ValidationMeta):
pass
class UserRepo(BaseRepo):
def save(self):
print("Saving user")
repo = UserRepo()
repo.save()
```
If someone forgets `save()`, Python raises the error at class creation time.
## Example 3: Singleton with metaclass
```python
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Database(metaclass=Singleton):
def __init__(self):
self.connected = True
db1 = Database()
db2 = Database()
print(db1 is db2) # True
```
## Safer alternatives you should consider first
Before metaclasses, usually you can solve problems using:
- decorators
- inheritance
- class decorators
- __init_subclass__ (modern and simpler)
Metaclasses are powerful, but they can make code harder for other developers to read.
## Graph: class creation pipeline
```mermaid
flowchart LR
A[Metaclass (type)] --> B[Creates Class]
B --> C[Class creates Objects]
C --> D[Instances]
```
## Key points
- Metaclass creates the class
- Python default metaclass is type
- Use only when you truly need class-creation control
- Prefer simpler alternatives when possible
#Python#Advanced#OOP