python 30メタクラス


メタクラス
1、pythonはすべてオブジェクトであり、クラス自体もオブジェクトであり、キーワードclassを使用すると、python解釈器はclassをロードするときにオブジェクトを作成します(ここで、オブジェクトはクラスのインスタンスではなくクラスを指します).
class Student:
    pass

s = Student()
print(type(s))  # 
print(type(Student))  # 

2、メタクラスメタクラスとはクラスのクラスであり、クラスのテンプレートメタクラスはクラスの作成方法を制御するために使用され、クラスがオブジェクトを作成するテンプレートであるようにメタクラスのインスタンスはクラスであり、クラスのインスタンスがオブジェクトであるようにする.typeはpythonの内蔵メタクラスであり、生成クラスを直接制御するために使用されます.pythonでclass定義されたクラスはtypeクラスがインスタンス化されたオブジェクトです.
3、クラスを作成する2つの方法:
#    
class Student:
    def info(self):
        print("---> student info")

#    
def info(self):
    print("---> student info")

Student = type("Student", (object,), {"info": info, "x": 1})

4、1つのクラスは自分のメタクラスを宣言していないで、デフォルトのそのメタクラスはtypeで、メタクラスtypeを使う以外に、ユーザーはtypeを継承することでメタクラスをカスタマイズすることができます
class Mytype(type):
    def __init__(self, a, b, c):
        print("===》         ")
        print("===》   __init__      :{}".format(self))
        print("===》   __init__      :{}".format(a))
        print("===》   __init__      :{}".format(b))
        print("===》   __init__      :{}".format(c))

    def __call__(self, *args, **kwargs):
        print("=====》     __call__  ")
        print("=====》   __call__ args:{}".format(args))
        print("=====》   __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 :{}".format(Student))
s = Student("xu")
print("  :{}".format(s))

#   :
#     ===》         
#     ===》   __init__      :
#     ===》   __init__      :Student
#     ===》   __init__      :()
#     ===》   __init__      :{'__module__': '__main__', '__qualname__': 'Student', '__init__': }
#     Student :
#     =====》     __call__  
#     =====》   __call__ args:('xu',)
#     =====》   __call__ kwargs:{}
#       :<__main__.student object="" at=""/>