Python - Metaclasses in Python (Detailed Explanation)
To understand metaclasses, you first need to understand how Python treats classes.
1. Everything in Python is an object
In Python:
-
Integers, strings, functions — all are objects
-
Even classes themselves are objects
For example:
class MyClass:
pass
print(type(MyClass))
Output:
<class 'type'>
This shows that MyClass is an object created by something called type.
2. What is a Metaclass?
A metaclass is the class of a class.
-
Just like a class defines how objects behave
-
A metaclass defines how classes behave
In simpler terms:
-
Object → created from a class
-
Class → created from a metaclass
By default, Python uses:
type
as the metaclass for all classes.
3. How Python Creates a Class
When you write:
class Person:
name = "John"
Python internally does something like:
Person = type("Person", (), {"name": "John"})
Here:
-
"Person"→ class name -
()→ base classes -
{...}→ attributes
So, type is acting as a metaclass that constructs the class.
4. Why Use Metaclasses?
Metaclasses allow you to control class creation.
You can:
-
Modify class attributes automatically
-
Enforce coding rules
-
Register classes
-
Add methods dynamically
They are used in frameworks like:
-
Django ORM
-
SQLAlchemy
-
Advanced libraries
5. Creating a Custom Metaclass
A metaclass is defined by inheriting from type.
Example:
class MyMeta(type):
def __new__(cls, name, bases, dct):
print("Creating class:", name)
return super().__new__(cls, name, bases, dct)
Now use it:
class Test(metaclass=MyMeta):
x = 10
Output:
Creating class: Test
This shows that the metaclass intercepts class creation.
6. Modifying Class Attributes Using Metaclass
You can change attributes before the class is created:
class UpperAttrMeta(type):
def __new__(cls, name, bases, dct):
new_dict = {}
for key, value in dct.items():
if not key.startswith("__"):
new_dict[key.upper()] = value
else:
new_dict[key] = value
return super().__new__(cls, name, bases, new_dict)
Usage:
class Sample(metaclass=UpperAttrMeta):
name = "Alice"
Now:
print(Sample.NAME) # Works
print(Sample.name) # Error
The metaclass modified attribute names to uppercase.
7. Key Methods in Metaclasses
__new__
-
Creates the class object
-
Most commonly used
__init__
-
Initializes the class after creation
__call__
-
Controls instance creation
Example:
class Meta(type):
def __call__(cls, *args, **kwargs):
print("Creating instance")
return super().__call__(*args, **kwargs)
8. When Should You Use Metaclasses?
Use metaclasses only when necessary, such as:
-
Building frameworks
-
Enforcing structure across multiple classes
-
Automatically modifying class definitions
Avoid them when:
-
Simpler solutions (functions, decorators, inheritance) work
-
Code readability is important
9. Simple Analogy
Think of it like this:
-
Blueprint → Class
-
Factory that creates blueprints → Metaclass
Most programmers use blueprints (classes)
Only advanced developers build factories (metaclasses)
10. Summary
-
Metaclasses define how classes are created
-
Default metaclass is
type -
They allow deep customization of class behavior
-
Mainly used in advanced frameworks and libraries
-
Powerful but should be used carefully