Metaclass &this is the class of the class. Whenever a class (object) is instantiated, the behavior of the object is determined by the class. The metaclass defines the behavior of the class itself.
The reason for using metaclasses is because Python classes are themselves objects. Since classes are objects, we can perform various operations with them, such as assigning them to a variable, copying, etc.
And since they are objects, we can create them dynamically like any other object.
< ! - ptnonline336 ->
To better understand the concept of metaclasses, we`ll first see how Python op thinns classes. The language defines everything as an object, be it
string or whatever.
If you remember to look at the type of any Python object, we`re using the
& gt; & gt; & gt; print (type (123)) & lt; class `int` & g t; & gt; & gt; & gt; print (type ([1, 2, 3])) & lt; class `list` & gt; & gt; & gt; & gt; class A (): ... def __init __ (self): ... pass ... & gt; & gt; & gt; a = A () & gt; & gt; & gt; print (type (a)) & lt; class `__main __. A` & gt;
As we can see, it returns the
class for each case. But to see how Python defines the class itself, we`ll just look at its type.
& gt; & gt; & gt; print (type (type (123)) & lt; class `type` & gt; & gt; & gt; & gt; print (type (A)) & lt; class` type` & gt;
As you can see, type (
class ) &this is the
type of the class! It turns out that the class is defined by the class itself? What is this phenomenon?
This is the concept of a metaclass that serves to define other classes, basically a class factory from which other classes such as
int s and
str s can be defined.
< img loading = "lazy" class = "alignnone" src = "https://pythononline.ru/wp-content/uploads/2020/09/img-103.png" alt = "Metaclass python" width = "581" height = "81" />
type &this is the metaclass that the language uses to create an object. (So every object has a type)
type &is a metaclass, we can create other classes from it.
We can create classes dynamically by instantiating from the constructor
type (name, bases, attr) :
type (name, bases, attr)
& gt; & gt; & gt; Animal = type (`Animal`, (), dict (__ init__ = lambda self: None, worth = lambda self, value: value))
This is the same as:
class Animal (): def __init __ (self): pass def worth (self, value): return value
The first code snippet is much easier to write than the second. Writing a class body even during dynamic declaration does not provide much flexibility.
Therefore, metaclasses provide a powerful and easy way to dynamically create new classes.
To create our own metaclass, we need to inherit the existing `type` metaclass and override some special methods:
__init __ (). It is responsible for creating an object and returning it.
The following snippet shows how a metaclass can be created:
class MyMetaclass (type): def __new __ (cls, name, bases, dict): print (`Creating a new object of`, name) # Invoke __new __ () method of th e metaclass type return super (MyMetaclass, cls) .__ new __ (cls, name, bases, dict) def __init __ (cls, name, bases, dict): print (`Initialising class`, name) super (MyMetaclass, cls) .__ init __ (name, bases, dict)
Now that we have created our own metaclass, we need to make sure that we create other classes that use our metaclass.
To do this, we we pass the
metaclass parameter to the new class definition, which tells the class to use our own metaclass as its own metaclass, rather than
class Student (metaclass = MyMetaclass): def __init __ (self, name): self.name = name def get_name (self): return self.name
Student < / code> uses
MyMetaclass as its metaclass. Therefore, when instantiating Student, our own metaclass methods will be called instead of the
stud = Student (`Amit `) print (stud.get_name ()) print (` Type of Student object: `, type (stud)) print (` Type of Student Class: `, type (Student))
Creating a new object of Student Initialising class Student Amit Type of Student object: & lt; class `__main __. Student` & gt; Type of Student Class: & lt; class `__main __. MyMetaclass` & gt;
Older versions of Python 2.7 or earlier use the
__metaclass__ keyword to specify the metaclass to use. Python3 changed this behavior to pass
metaclass as a parameter.
While metaclasses serve as a very powerful way to create custom APIs and define their behavior in creation time of objects and classes, they are very rarely ever used in practice, since there are other workarounds for them. You can read more on this topic at stackoverflow.com a>.