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


  •