Metaclasses in Python
Everything is an object in Python programming, the data types are classes and the variables are instances (object) of these classes.
Example:
class Exampleclass(): pass example_class = Exampleclass() print(example_class) type(Exampleclass)
Output:
A Class is also an instance of something called a Metaclass, a special class type that creates these class objects.
In short, Metaclass creates Classes and Classes create objects.
A metaclass defines how a class behaves. A class defines how the instance of the class behaves. For a better understanding of metaclasses, we’ll have to first work with Python classes.
Example:
type(Exampleclass) type(type)
Output:
We had expected the type of Exampleclass() we created above to be a class, but it’s not. We notice that Exampleclass() is an instance of type, and the type of type itself is type. Also, type enables us to create classes dynamically.
Now, we understand that Python creates classes using a metaclass. Whenever we call a class to create a class, it is the metaclass that creates it.
In Python, the __class__ attribute enables us to check the type of the current instance.
We’ve already seen that type creates classes. Hence when we check the __class__ of __class__, it should return type
Example:
article = 'i2tutorials' article.__class__ type(article) type(str)
Output:
Creating custom Metaclass
In Python, we can customize the class creation process by passing the “metaclass” keyword in the class definition. We can also do this by inheriting a class which has already passed in this keyword.
Example:
class meta(type): pass class myclass(metaclass=meta): pass class subclass(myclass): pass print(type(meta)) print(type(myclass)) print(type(subclass))
Output:
We can see below that the type of meta class is type and that the type of myclass and subclass is meta.
When we only define a class and no metaclass is defined, the default type metaclass will be used if a given metaclass is not an instance of type().
__new__() and __init__():
To create our custom metaclass, our custom metaclass has to inherit type metaclass and usually override –
- __new__(): This method is called before the __init__() method. It creates the object and returns it. We can control how the objects get created by overriding this method.
- __init__(): This method just initializes the created object passed as a parameter.
Example:
class ClassOne(type): def__new__{cls, name, bases, dict): pass class Classtwo(type): def__init__{cls, name, bases, dict): pass
Output:
When do we use Metaclasses?
- When our need is to change class automatically, once it’s created,
- For API development.