Metaclasses in Python

Metaclasses in Python

Rayven Esplanada Aug-10, 2021 Jun-03, 2021 Python Python Class

This tutorial will discuss what metaclasses are in an object-oriented context in Python.

Metaclasses in Python

Simply put, a metaclass defines the behavior of a class. A regular class defines how an object or an instance of a class behaves.

In Python, metaclasses are pre-made and implicit; this means that a metaclass is made in the background upon creating a class.

the object Base Class in Python

In Python, every class that is created implicitly inherits the base class object. Within the object class are built-in private methods like __init__ and __new__. Before a class even starts creating their own fields, functions, and attributes, they inherit whatever attributes there are in the object class.

Let’s create a new class, ChildObject, for example. Within this class is a declaration of a single attribute and a single function.

class ChildObject:
    num = 1
    
    def printStatement():
        print("This is a child object.")

To verify that the ChildObject class inherits whatever attributes and functions are in the object class, use the dir() function, which returns a list of all the functions and attributes defined in a specified object.

print(dir(ChildObject))

Output:

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'num', 'printStatement']

Observe that before the num attribute and the printStatement function, there are quite a few private attributes and functions that are not explicitly defined in ChildObject; this means they are either implicitly defined within the class or are inherited from the object class.

Let’s check the attributes and functions of the object class using the same function dir():

print(dir(object))

Output:

['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

the type Metaclass in Python

Now that we’ve covered the object class, let’s discuss the actual metaclass in Python, type. Again, a metaclass is a class that instantiates and defines the behavior of another class.

Two functions can expose the metaclass of a given class: type() and __class__. Both of these functions output the class of the argument given.

For example, let’s use the type() and __class__ functions on the given ChildObject class from the above examples.

class ChildObject:
    num = 1
    
    def printStatement():
        print("This is a child object.")
        
print(type(ChildObject))
print(ChildObject.__class__)

Output:

<class 'type'>
<class 'type'>

Both functions output <class 'type'>. This signals that the ChildObject class is of a type type. type is the metaclass of the ChildObject class and any other class for that matter.

In summary, type is the metaclass that implicitly defines the behavior of any instantiated class. This isn’t considered common knowledge because this is done in the background of the code without the developer’s interference. So the concept of a metaclass is only known if someone digs deep into the Python source code and documentation.

Related Article - Python Class

  • Python Generator Class
  • Data Class Inheritance in Python
  • Serialize a Python Class Object to JSON
  • Python Abstract Property
  • Python Class Factory
  • Python Class Equality