Metaclasses in Python (The Most Advanced OOP Concept)

@amitmund June 17, 2026

Metaclasses in Python (The Most Advanced OOP Concept)

Metaclasses are the class of a class.

In Python: - Objects are created from classes - Classes are created from metaclasses

Default metaclass: type


1. What is a Metaclass?

Everything in Python is an object:

  • 10 → object
  • "hello" → object
  • class → object

But classes themselves are created by something:

👉 That something is a METACLASS


Flow of Creation

Object creation flow:

Instance → Class → Metaclass (type)


Graph

Instance (obj) ↓ Class (MyClass) ↓ Metaclass (type)


2. type() — The Built-in Metaclass

type() has 3 uses:


(1) Check type

x = 10
print(type(x))

Output: int


(2) Create class dynamically

MyClass = type(
    "MyClass",
    (),
    {"x": 10}
)

obj = MyClass()
print(obj.x)

Output: 10


Graph

type() ↓ Creates class dynamically ↓ Class becomes object


Real World Example

Dynamic API models: - frameworks create classes at runtime - ORM models (Django)


3. Custom Metaclass

We can control class creation using metaclasses.


Example

class MyMeta(type):
    def __new__(cls, name, bases, dct):
        print("Creating class:", name)
        return super().__new__(cls, name, bases, dct)


class MyClass(metaclass=MyMeta):
    x = 10

obj = MyClass()

Output: Creating class: MyClass


What is happening?

  1. Class definition starts
  2. Metaclass intercepts creation
  3. __new__ runs
  4. Class is modified/created

Graph

Class Definition ↓ Metaclass (__new__) ↓ Class Created ↓ Object Instantiated


4. Why Metaclasses Exist

They allow:

  • Automatic validation
  • Class modification
  • Framework automation
  • Enforcing rules

Real World Example (Framework Style)

class Meta(type):
    def __new__(cls, name, bases, dct):
        if "run" not in dct:
            raise Exception("Class must define run()")
        return super().__new__(cls, name, bases, dct)


class Service(metaclass=Meta):
    def run(self):
        print("Running service")

If you remove run():

Exception: Class must define run()


5. Django ORM Example (Conceptual)

Django models behave like:

class User(models.Model):
    name = models.CharField()

Internally: - metaclass reads fields - builds SQL mapping - registers model


6. Custom Metaclass with Modification

class UpperMeta(type):
    def __new__(cls, name, bases, dct):
        new_dct = {}

        for k, v in dct.items():
            if not k.startswith("__"):
                new_dct[k.upper()] = v
            else:
                new_dct[k] = v

        return super().__new__(cls, name, bases, new_dct)


class Demo(metaclass=UpperMeta):
    name = "Aman"
    age = 20

print(hasattr(Demo, "name"))
print(hasattr(Demo, "NAME"))

Output: False True


7. Real World Use Cases

System Use of Metaclass
Django ORM model creation
Pydantic validation schema
ORMs table mapping
Frameworks auto registration

8. type vs Custom Metaclass

Feature type Custom Metaclass
Built-in Yes No
Control Low High
Framework use Internal Advanced

9. Common Mistakes


Mistake 1: Confusing object vs class

Wrong thinking: metaclass creates objects

Correct: metaclass creates classes


Mistake 2: Overusing metaclasses

Metaclasses are powerful but rare in application code.

Use only when needed.


Mistake 3: Forgetting type inheritance

class Meta(type):
    pass

10. Graph: Full Python Object Model

value ↓ object instance ↓ class ↓ metaclass (type) ↓ Python runtime


11. Real World Analogy

Concept Real World
Object Employee
Class Job Role
Metaclass HR system defining roles

12. Homework 1

Create a metaclass that: - prints class name - blocks classes without method "execute"

Solution:

class CheckMeta(type):
    def __new__(cls, name, bases, dct):
        if "execute" not in dct:
            raise Exception("Missing execute method")
        print("Creating:", name)
        return super().__new__(cls, name, bases, dct)


class Job(metaclass=CheckMeta):
    def execute(self):
        print("Running job")

13. Homework 2

Create metaclass that converts all attributes to uppercase.

Solution:

class UpperMeta(type):
    def __new__(cls, name, bases, dct):
        new_dct = {}

        for k, v in dct.items():
            if not k.startswith("__"):
                new_dct[k.upper()] = v
            else:
                new_dct[k] = v

        return super().__new__(cls, name, bases, new_dct)


class Test(metaclass=UpperMeta):
    value = 100

print(hasattr(Test, "VALUE"))

14. Why Metaclasses Matter

They power: - Django ORM - Flask extensions - FastAPI internals - Pydantic validation - Dependency injection systems


15. Final Mental Model

Class creation process:

  1. Python reads class
  2. Metaclass intercepts
  3. Class is modified/generated
  4. Object is created from class

Next Advanced Topics

  • __new__ vs __init__ deep dive
  • Descriptor + Metaclass combination
  • Django ORM internals
  • Dependency Injection systems
  • Python interpreter internals
  • AST (Abstract Syntax Tree) ```
0 Likes
46 Views
0 Comments

Filters

No filters available for this view.

Reset All