A metaclass is a class/object which defines a type/class of other classes. In Python a metaclass can be a class, function or any object that supports calling an interface. This is because to create a class object; its metaclass is called with the class name, base classes and attributes (methods). When no metaclass is defined (which is usually the case), the default metaclass type is used.

For example:



When a class is created, the interpreter:

  1. Gets the name of the class.
  2. Gets the base classes of the class.
  3. Gets the metaclass of the class. If it is defined, it will use this first. Otherwise, it will check in the base classes for the metaclass. It it can't find a metaclass in the base class, the type object is used instead.
  4. Gets the variables/attributes in the class and stores them as a dictionary.
  5. Passes this information to metaclass as metaclass(name_of_class, base_classes, attributes_dictionary) and it returns a class object.

For example:

When type is called, its __call__ method is called. This method in turn calls the __new__ and __init__ methods. The __new__ method creates a new object, whereas the __init__ method initializes it. We can easily play with methods. This is a working example:



When running the code, we get:

When running the code, we get:


Normally we need to override only one method __new__ or __init__. We can also use function instead of a class. Here is an example:



Gives us the following output:


Gives us the following output:


Other then modifying base classes and methods of classes to be created, metaclasses can also modify instance creation process. This is because when we create an instance (ik = Kls()), this is like calling the class Kls. One point to note is that whenever we call an object its type's __call__ method is called. So in this case the class type is metaclass hence its __call__ method will be called. We can check like this:








The output is as follows:

Equipped with this information, if we go to the start of our discussion about the class creation process, it ended with a call to the metaclass object, which provided a class object. It was like this:

Hence this call should call the metaclass's type. The metaclass type is the metaclass's metaclass! We can check this as follows:








Gives us the following output:

About The Author