In simple terms, metaprogramming is a code that manipulates other codes. We will look into detail about metaprogramming in this article and also find out when to use it. We will also learn the alternatives to it in python for data science.
Everything has an association type in Python. A variable having integer value has association type int. The type of anything can be found using type() function.
We can create a new type by making a class of that type. Consider the example below.
As a class is an object so, it is an instance of Metaclass. A special class type creates these class objects. The type class responsible for making classes is default metaclass. Let us look into an example.
As classes are objects so, they can be modified in the same way. Let us make this clear through an example.
The above figure shows that metaclass creates class, and class creates object. So, we can customize the metaclass to change the way classes are being generated just by performing extra actions or injecting some codes. For most of the problems, both metaclass and non-metaclass solutions are available. But in some cases, only metaclasses can provide the solution.
Creating a Custom Metaclass:
For the creation of custom metaclass, the custom metaclass should inherit the type metaclass and usually override.
- __new__(): It is call before __init__(). It first creates an object and then returns it. This method can be overridden in order to control creation of objects.
- __init__(): This is there to initialize the object passed as parameter.
Classes can be created using type() function directly.
- When we call the function type() using one argument, it returns the type.
- When we call it using three arguments, it creates a class. The arguments which have to be passed are
- Class name
- Tuple which is having base class inherited by class.
- Class Dictionary (It is a local namespace for class and contains class methods and variables).
Now we will look at an illustrative example where a metaclass is created without using type() directly.
Problem solving using metaclass:
Some problems can be solved using decorators and metaclass both, but in some cases, only metaclass is able to solve the problem. Let us look into an example of problem due to code repetition.
The above solution is fine, but in case we want to apply this method decorator to all subclasses which inherit the Calc class it will be very difficult.
In such cases we should use metaclass based solutions as we know that every subclass should have this debug property.
Cases, where we use metaclass, are given below:
- In case we have a situation in which we need to propagate down the inheritance hierarchies and affect the subclasses.
- In case we want to change the class automatically when it is created.
- API developers use metaclass.