Python Metaclasses

The word “meta” means self-referential. A metaclass is a class whose instances are classes. Like an “ordinary” class defines the behavior of the instances of the class, a metaclass defines the behavior of classes and their instances.

Objects are instances of Classes and the Classes are instances of Metaclasses. We create objects from classes and then we create classes out of metaclasses. In Python, type is the default metaclass for all the classes but this can be customized as we need.

The term metaprogramming refers to the potential for a program to have knowledge of or manipulate itself. Python supports a form of metaprogramming for classes called metaclasses.

Old-Style vs. New-Style Classes

With old-style classes, class and type are not quite the same thing. An instance of an old-style class is always implemented from a single built-in type called instance. If obj is an instance of an old-style class, obj.__class__ designates the class, but type(obj) is always instance.

New-style classes unify the concepts of class and type. If obj is an instance of a new-style class, type(obj) is the same as obj.__class__.

Type and Class

In Python 3, all classes are new-style classes. Thus, in Python 3 it is reasonable to refer to an object’s type and its class interchangeably.

In Python 2, classes are old-style by default. Prior to Python 2.2, new-style classes weren’t supported at all. From Python 2.2 onward, they can be created but must be explicitly declared as new-style.

>>> class Foo:
...     pass
>>> x = Foo()

>>> type(x)
<class '__main__.Foo'>

>>> type(Foo)
<class 'type'>

But the type of Foo, the class itself, is type. In general, the type of any new-style class is type. The type of the built-in classes you are familiar with is also type.

type is a metaclass, of which classes are instances. Just as an ordinary object is an instance of a class, any new-style class in Python, and thus any class in Python 3, is an instance of the type metaclass.

In the above case:

  • x is an instance of class Foo.
  • Foo is an instance of the type metaclass.
  • type is also an instance of the type metaclass, so it is an instance of itself.
Python class chain