A Python Metaclass sets the behavior and rules of a class. Metaclass helps in modifying the instantiation of a class and is fairly complex and one of the advanced features of Python programming. Through this article, I will be discussing in-depth concepts of Python Metaclass, its properties, how and when to use a Metaclass in Python. This article covers the following concepts:
What is Python Metaclass?
Python Metaclass is one of the advanced features associated with Object-Oriented Programming concepts of Python. It determines the behavior of a class and further helps in its modification.
Every class created in Python has an underlying Metaclass. So when you’re creating a class, you are indirectly using the Metaclass. It happens implicitly, you don’t need to specify anything.
Metaclass when associated with metaprogramming determines the ability of a program to manipulate itself. Learning Metaclass might seem complex but let’s get a few concepts of classes and objects out of the way first, so that it’s simple to understand.
Classes and Objects in Python
A class is a blueprint, a logical entity having objects. A simple class when declared does not have any memory allocated, it happens when an instance of a class is created.
Through the objects created, one can access the class. The class simply works as a template. The property of an object essentially means that we can interact with it at runtime, pass parameters like variables, store, modify, and can also interact with it.
The class of an object can be checked by using the __class__ attribute. Let’s see this simple example:
class Demo: pass #This is a class named demo test=Demo() print(test.__class__) #shows class of obj print(type(test)) #alternate method
Output: <class '__main__.Demo'>
Python heavily deals with the concept of classes and objects and allows easy and smooth application development. But what makes Python different from languages like Java and C? Everything in Python can be defined as an object having attributes and methods. Keynote is that classes in Python are nothing but another object of a bigger class.
A class defines rules for an object. Similarly, a Metaclass is responsible for assigning behaviors for the classes. We have learned that Class is an object, and like every object has an instance, a class is an instance of a Metaclass.
But there are languages like Ruby and Objective-C which support Metaclasses as well. So, what makes Python Metaclass better and why should you learn it? The answer is the dynamic class in Python. Let’s take a closer look at it.
Dynamic Class in Python
Python is a dynamic programming language and allows the creation of a class at runtime. Unlike other languages like C++, which only allows the class creation at compile time. In terms of flexibility, Python has an advantage over other languages that are statically typed.
The difference between dynamic and statically typed language isn’t much, but in Python, it becomes more useful because it provides metaprogramming.
But what if I tell you that there’s another key feature that distinguishes Python from other programming languages?
Languages like Java or C++ have data types like float, char, int, etc. whereas Python treats each variable as an object. And each object belongs to a class like an int class or str class. You can simply check the class of any variable using a built-in function called type().
number = 10993 print("Type associated is:", type(number)) name = "Aishwarya" print("Type associated is:", type(name))
Type associated is: <class 'int'>
Type associated is: <class 'str'>
Now that you understand everything in Python has a type associated with it. In the next topic, we will try to understand how Metaclass actually works.
How Does Python Metaclass Work?
Whenever a class is created the default Metaclass which is type class gets called instead. Metaclass carries information like name, set of a base class, and attributes associated with the class. Hence, when a class is instantiated type class is called carrying these arguments. Metaclass can be created via two methods:
- Type class
- Custom Metaclass
Let’s move on to type class and how you can create one.
Python has a built-in Metaclass called type. Unlike Java or C, where there are primary data types. Every variable or object in Python has a class associated with it. Python use Type class behind-the-scenes to create all the classes. In the previous topic, we saw how we can check the class of an object by using type(). Let’s take an example of how we can define a new type, by creating a simple class.
class Edureka(): obj = Edureka() print(type(obj))
Output: <class '__main__.Edureka'>
Output: <class 'type'>
In the above code, we have a class called Edureka, and an object associated. We created a new type called Edureka by simply creating a class named itself after the type. In the second code, when we check the type of Edureka class, it results as ‘type’.
So, unless defined otherwise, Metaclasses use type class to create all the other classes. We can access Type class via two methods:
When we pass parameters through type class, it uses the following syntax.
type(__name__, __base__, attributes)
- the name is a string and carries the class name
- the base is a tuple and helps create subclasses
- an attribute is a dictionary and assigns key-value pairs
Since classes in Python behave similar to the objects, their behavior could be altered in the same way. We can add or remove methods within a class similar to how we do with objects.
Now that you know Metaclass creates all the other classes in Python and defines their behavior using type class. But then you must be wondering, is there any other way we can create Metaclass? So, let’s see how to create a custom Metaclass that.
Custom Metaclass in Python
Now that we know and understand how the type class works. It’s time to learn how we can create our custom Metaclass. We can modify the working of classes by carrying actions or code injection. To achieve this, we can pass Metaclass as a keyword while creating a class definition. Alternatively, we can achieve this by simply inheriting a class that has been instantiated through this Metaclass keyword.
At the time of creating a new class, Python looks for the __metaclass__ keyword. In case, if it isn’t present. It follows the type class hierarchy.
After Python executes all the dictionary in a namespace, it invokes type object which creates objects of a class. There are two methods that we can use to create custom Metaclass.
class EduFirst(type): def __new__(cls, name, base_cls, dict): pass class EduSecond(type): def __init__(self, name, base_cls, dict): pass
Let me explain these two methods in detail:
- __new__(): is used when a user wants to define a dictionary of tuples before the class creation. It returns an instance of a class and is easy to override/manage the flow of objects.
- __init__(): It’s called after the object has already been created and simply initializes it.
What is __call__ in Python?
In the official Python documents, the __call__ method can be used to define a custom Metaclass. Also, we can override other methods like __prepare__ when calling a class to define custom behavior.
Much like how a class behaves like a template to create objects, in the same way, Metaclass acts like a template for the class creation. Therefore, a Metaclass is also known as a class factory.
See the next example:
class Meta(type): def __init__(cls, name, base, dct): cls.attribute = 200 class Test(metaclass = Meta): pass Test.attribute
Metaclass allows class customization. There are various other effective and much simpler ways through which the same output can be achieved. One such example is using Decorators.
Decorator vs Metaclass
Decorator is a popular feature of Python which allows you to add more functionality to the code. A decorator is a callable object which helps modify the existing class or even a function. During compilation, part of code calls and modifies another part. This process is also known as metaprogramming.
|Returns the same class after making changes
|We use Metaclass whenever a new class is created|
|Lacks flexibility||Provides flexibility and customization of classes|
|Isn’t compatible to perform subclassing||Provides subclassing by using inheritance and converting object methods to static methods for better optimization|
def decorator(cls): class NewClass(cls): attribute = 200 return NewClass @decorator Class Test1: pass @decorator Class Test2: pass Test1.attribute Test2.attribute
Decorator in Python is a very useful and powerful tool that helps change the behavior of a function without actually changing any of the code. This comes handy when you want to modify a part of the program while debugging, instead of rewriting the function or changing the entire program. Instead, you can simply write a single line decorator and it will take care of the rest.
This brings us to the end of the session. Hopefully, this article helped you understand what is Metaclass and how and when to use it.
If you found this article on “Python Metaclass” relevant, check out Edureka’s Python Programming Certification Course a trusted online learning company with a network of more than 250,000 satisfied learners spread across the globe.
We are here to help you with every step on your journey and come up with a curriculum that is designed for students and professionals who want to be a Python developer. The course is designed to give you a head start into Python programming and train you for both core and advanced Python concepts along with various Python frameworks like Django.
If you come across any questions, feel free to ask all your questions in the comments section of “Python Metaclass”. Our team will be glad to answer.