đź§© Everything is an Object in Python
In Python, almost everything is treated as an object. This includes not only variables and data structures but also functions and classes. Since classes are objects too, they can be:
Most importantly, this object-oriented nature allows classes to generate other classes. The special classes that do this are called metaclasses.
🔑 What is a Metaclass?
Just as a class defines how an object behaves, a metaclass defines how a class behaves. By default, the metaclass for all Python classes is type
.
👉 In short, metaclasses are the blueprints for classes.
🔨 The type
Class – The Default Metaclass
Normally, we create classes using the class
keyword:
class FoodType(object):
def __init__(self, ftype):
self.ftype = ftype
def getFtype(self):
return self.ftype
fType = FoodType(ftype='Vegetarian')
print(fType.getFtype())
Output:
Vegetarian
But internally, Python uses the built-in type
class to do the same thing:
def init(self, ftype):
self.ftype = ftype
def getFtype(self):
return self.ftype
FoodType = type('FoodType', (object,), {
'__init__': init,
'getFtype': getFtype
})
fType = FoodType(ftype='Vegetarian')
print(fType.getFtype())
Output:
Vegetarian
Here’s how the type
arguments work:
First argument: the class name (string).
Second argument: tuple of base classes (for inheritance).
Third argument: dictionary of attributes and methods.
🧬 Creating Subclasses with type
We can also use type
to create subclasses dynamically.
Normal way using class
:
class FoodType(object):
def __init__(self, ftype):
self.ftype = ftype
def getFtype(self):
return self.ftype
class VegType(FoodType):
def vegFoods(self):
return {'Spinach', 'Bitter Gourd'}
vType = VegType(ftype='Vegetarian')
print(vType.getFtype())
print(vType.vegFoods())
Dynamic way using type
:
def init(self, ftype):
self.ftype = ftype
def getFtype(self):
return self.ftype
FoodType = type('FoodType', (object,), {
'__init__': init,
'getFtype': getFtype
})
def vegFoods(self):
return {'Spinach', 'Bitter Gourd'}
VegType = type('VegType', (FoodType,), {
'vegFoods': vegFoods
})
vType = VegType(ftype='Vegetarian')
print(vType.getFtype())
print(vType.vegFoods())
⚙️ Writing Custom Metaclasses
Metaclasses are created by inheriting from type
and customizing the __new__
method.
class MetaCls(type):
def __new__(cls, clsname, superclasses, attrs):
print("Creating class:", clsname)
return super().__new__(cls, clsname, superclasses, attrs)
C = MetaCls('C', (object,), {})
print(type(C))
Output:
Creating class: C
<class '__main__.MetaCls'>
Here, the class C
was created by MetaCls
instead of the default type
.
🏗️ Metaclass Inheritance
When a class is built using a metaclass, its subclasses also inherit that metaclass unless specified otherwise. However, Python does not allow a single class to be created from two conflicting metaclasses — it raises a TypeError because a class can only have one metaclass.
🛠️ Use Cases of Metaclasses
Metaclasses are rarely needed in day-to-day programming, but they become valuable in special cases.
1. âś… Class Verification
They can enforce that a class must follow certain rules:
class MainClass(type):
def __new__(cls, name, bases, attrs):
if 'foo' not in attrs and 'bar' not in attrs:
raise TypeError(f"Class {name} must define foo or bar")
return super().__new__(cls, name, bases, attrs)
class SubClass(metaclass=MainClass):
foo = 42
2. đźš« Preventing Attribute Inheritance
Useful for abstract classes to ensure subclasses don’t inherit unwanted methods.
3. ⚡ Dynamic Class Generation
They allow dynamic creation of classes at runtime — helpful in frameworks and plugins.
🔍 Key Points About Metaclasses
Classes create objects, and metaclasses create classes.
Python’s default metaclass is type
.
You can write custom metaclasses by inheriting from type
.
They’re useful for validation, enforcing rules, and dynamic class generation.
📌 Summary
Metaclasses in Python are essentially blueprints for classes. While every class by default is created using the type
metaclass, you can define your own to control how classes are built. They are advanced tools that make sense in frameworks, code validation, and dynamic class creation. In short: objects come from classes, and classes come from metaclasses. 🚀