Skip to content

metaclass

In Python, a metaclass is the class of a class. Every object is an instance of some class, and classes are themselves objects, so every class is an instance of a metaclass.

When you write a class statement, Python gathers three things: the class name, the tuple of base classes, and the namespace produced by running the class body. It hands those to a metaclass, which builds and returns the finished class object:

Name, bases, and namespace feed a metaclass, whose __new__() returns the class object, an instance of that metaclass.
The Path From a Class Statement to a Class Object

The default metaclass is type, so type(int) is type itself. You get your own by subclassing type and naming it with metaclass= in the class header. Overriding its __new__() special method lets you inspect or adjust a class at definition time, before anything instantiates it.

That hook is how libraries auto-register subclasses, enforce that required methods are present, or attach attributes across a hierarchy. Django’s models and abstract base classes both rely on metaclasses. Most code never needs one, though, because __init_subclass__() and class decorators cover much of the same ground with less machinery.

Example

Say you’re building a plugin system and you want every plugin class to add itself to a registry, without each author remembering to call a registration function:

Language: Python
>>> class PluginMeta(type):
...     registry = {}
...     def __new__(mcs, name, bases, namespace):
...         cls = super().__new__(mcs, name, bases, namespace)
...         if bases:
...             PluginMeta.registry[name.lower()] = cls
...         return cls
...

>>> class Plugin(metaclass=PluginMeta):
...     pass
...
>>> class CsvExporter(Plugin):
...     pass
...
>>> class JsonExporter(Plugin):
...     pass
...

>>> list(PluginMeta.registry)
['csvexporter', 'jsonexporter']
>>> PluginMeta.registry["csvexporter"]
<class '__main__.CsvExporter'>

PluginMeta.__new__() runs once per class statement, as Python executes the definition, so the two exporters land in the registry without any extra call. The if bases check skips Plugin itself, since a base with no bases of its own isn’t a plugin. Every class built with metaclass=PluginMeta inherits that behavior, including ones defined in other modules.

Python Metaclasses and Metaprogramming

Tutorial

Python Metaclasses

How Python's metaclasses work as an OOP concept, what they are good for—and why you might want to avoid them in your own programs.

advanced python

For additional information on related topics, take a look at the following resources:

Have a question about this? Mentor AI can show you examples, compare related terms, and point you to tutorials.


By Martin Breuss • Updated Oct. 4, 2026