Detailed Explanation of Metaclass of Python Foundation

  • 2021-11-02 01:40:27
  • OfStack

1. python is an object, and the class itself is an object. When using the keyword class, the python interpreter will create an object when loading class (the object here refers to the class instead of the instance of the class)


class Student:
    pass
 
s = Student()
print(type(s))  # <class '__main__.Student'>
print(type(Student))  # <class 'type'>

2. What is a metaclass

Metaclasses are classes of classes and templates of classes
Metaclasses are used to control how classes are created, just as classes are templates for creating objects
An instance of a metaclass is a class, just as an instance of a class is an object.
type is a built-in class of python, which is used to directly control the generated class. Any class defined by class in python is actually an object instantiated by type class

3. Two ways to create a class:


#  Method 1
class Student:
    def info(self):
        print("---> student info")
 
#  Method 2
def info(self):
    print("---> student info")
 
Student = type("Student", (object,), {"info": info, "x": 1})

The 4.1 class does not declare its own metaclass, and its metaclass is type by default. In addition to using the metaclass type, users can also customize the metaclass by inheriting type


class Mytype(type):
    def __init__(self, a, b, c):
        print("=== "   Actor class constructor ")
        print("=== "   Metaclass __init__  No. 1 1 Parameters: {}".format(self))
        print("=== "   Metaclass __init__  No. 1 2 Parameters: {}".format(a))
        print("=== "   Metaclass __init__  No. 1 3 Parameters: {}".format(b))
        print("=== "   Metaclass __init__  No. 1 4 Parameters: {}".format(c))
 
    def __call__(self, *args, **kwargs):
        print("===== "   Actor class __call__ Method ")
        print("===== "   Metaclass __call__ args : {}".format(args))
        print("===== "   Metaclass __call__ kwargs : {}".format(kwargs))
        obj = object.__new__(self)  # object.__new__(Student)
        self.__init__(obj, *args, **kwargs)  # Student.__init__(s, *args, **kwargs)
        return obj
 
 
class Student(metaclass=Mytype):  # Student=Mytype(Student, "Student", (), {}) ---> __init__
    def __init__(self, name):
        self.name = name  # s.name=name
 
print("Student Class: {}".format(Student))
s = Student("xu")
print(" Example: {}".format(s))
 
#  Results: 
#     === "   Actor class constructor 
#     === "   Metaclass __init__  No. 1 1 Parameters: <class '__main__.Student'>
#     === "   Metaclass __init__  No. 1 2 Parameters: Student
#     === "   Metaclass __init__  No. 1 3 Parameters: ()
#     === "   Metaclass __init__  No. 1 4 Parameters: {'__module__': '__main__', '__qualname__': 'Student', '__init__': <function Student.__init__ at 0x00000269BCA9A670>}
#     Student Class: <class '__main__.Student'>
#     ===== "   Actor class __call__ Method 
#     ===== "   Metaclass __call__ args : ('xu',)
#     ===== "   Metaclass __call__ kwargs : {}
#      Example: <__main__.Student object at 0x00000269BC9E8400>

Related articles: