Python 3.12 ·
✓ verified by execution on 2026-07-30
When you define a class in Python, you’re creating a template for building objects. But what builds the class itself? The answer is a metaclass.
A metaclass is a “class of a class”. Just as an object is an instance of a class, a class is an instance of a metaclass. By default, all classes in Python are constructed using the built-in type() function, which acts as the default metaclass.
Here is a visualization distinguishing between class creation time and instance creation time:
The Metaclass Object Model: type creates the class, the class creates the instance.
python · visualize
class MyMeta(type): def __new__(mcs, name, bases, namespace): print(f"1. Creating class {name}") return super().__new__(mcs, name, bases, namespace)print("0. Before class definition")class MyClass(metaclass=MyMeta): passprint("2. After class definition")m = MyClass()print("3. Instance created")
Notice that the metaclass __new__ method runs while the class is being defined, completely independent of when (or if) you ever instantiate it!
The Default Metaclass
If you don’t specify a metaclass, Python uses type.
python
class MyClass: passprint(type(MyClass))
Output
<class 'type'>
Your output
Customizing Class Creation with __new__
You can write your own metaclass by inheriting from type. The most common method to override is __new__, which takes four arguments:
mcs: The metaclass itself.
name: The name of the class being created.
bases: A tuple of base classes.
namespace: A dictionary containing the class attributes and methods.
Let’s modify a class namespace before the class even exists by converting all its custom attributes to uppercase!
python
class UppercaseMeta(type): def __new__(mcs, name, bases, namespace, **kwargs): uppercase_attr = {k.upper(): v for k, v in namespace.items() if not k.startswith('__')} return super().__new__(mcs, name, bases, uppercase_attr, **kwargs)class MyClass(metaclass=UppercaseMeta): my_attr = 10print(hasattr(MyClass, 'my_attr'))print(hasattr(MyClass, 'MY_ATTR'))
Output
False
True
Your output
Class Factories and Registries
Metaclasses are sometimes referred to as class factories. A very common use case is building a registry of plugins. Whenever a new subclass is defined, the metaclass can automatically record it in a dictionary.
The appropriate metaclass for a class is determined by looking at its explicit metaclass keyword argument or by checking its base classes. If a base class has a custom metaclass, the derived class will inherit it automatically.
python
class Meta(type): passclass Base(metaclass=Meta): passclass Derived(Base): passprint(type(Derived))
Output
<class '__main__.Meta'>
Your output
Metaclass Conflicts
Because a class inherits metaclasses from its bases, multiple inheritance can cause problems. If you try to inherit from two classes that have different, unrelated metaclasses, Python won’t know which one to use to construct your new class!
python
class MetaA(type): passclass MetaB(type): passclass A(metaclass=MetaA): passclass B(metaclass=MetaB): passtry: class C(A, B): passexcept TypeError as e: print('TypeError')
Output
TypeError
Your output
To resolve this, you would have to manually create a new metaclass that inherits from both MetaA and MetaB, and specify it as the metaclass for C.
Metaclass vs __init_subclass__
While metaclasses are incredibly powerful, they are often overkill. Since Python 3.6, the __init_subclass__ classmethod provides a much simpler way to customize class creation (like building registries) without the complexity of metaclasses. The golden rule is: If __init_subclass__ can solve your problem, use it instead of a metaclass.
Check yourself
What is a metaclass, in one sentence?
Reveal answer
A class whose instances are themselves classes — type is the default metaclass: it creates class objects, exactly as a class creates instances.
When does a metaclass __new__ run?
Reveal answer
Once, when the class itself is defined — Metaclass hooks fire at class-creation time, which is why they suit registration and validation of the class body.
What problem do metaclasses typically solve?
Reveal answer
Registering or validating subclasses automatically as they are defined — Auto-registration (plugin systems) and enforcing that subclasses declare required attributes are the classic uses.
What is usually the better first choice than a metaclass?
Reveal answer
__init_subclass__ or a class decorator — __init_subclass__ covers most subclass-registration needs with far less machinery. Reach for a metaclass only when it cannot.
Challenges
Challenge 1 +100 XP
Create a metaclass `RequireDocstringMeta` that raises a `TypeError` if a class is defined without a docstring (`__doc__`). Apply it to `StrictClass`.
python
Test 1 — expects ""
Need a hint? (−25% XP)
Check the `namespace` dictionary for the `__doc__` key inside the metaclass's `__new__` method.
Show solution (0 XP)
class RequireDocstringMeta(type): def __new__(mcs, name, bases, namespace): if '__doc__' not in namespace or not namespace['__doc__']: raise TypeError('Class must have a docstring') return super().__new__(mcs, name, bases, namespace)class StrictClass(metaclass=RequireDocstringMeta): """This class has a docstring.""" pass
Challenge 2 +100 XP
Create a metaclass `SingletonMeta` that ensures only one instance of a class is ever created. Apply it to the `Database` class.
python
Test 1 — expects ""
Need a hint? (−25% XP)
Override the `__call__` method on the metaclass to intercept when the class is instantiated.
Show solution (0 XP)
class SingletonMeta(type): _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super().__call__(*args, **kwargs) return cls._instances[cls]class Database(metaclass=SingletonMeta): pass