python元类
引子:
理解python的元类,要明白python一切皆对象
代码:
# -*- coding: utf-8 -*- """ @author:yuan_x @software:PyCharm @file:meta_class_stu2.py @time:2021/3/6 10:43 上午 """ """ metaclass 作用 用来指定 当前类 由谁创建 若不指定 默认用type创建 下方例子: 1 在定义 bar 的时候 会先调用 metaclass类也就是foo的 __new__ __init 但这时候 生成的 是bar 这个类 而不是bar的实例 2 在 bar()实例的时候 才会去调用 metaclass的 __call__ 正常情况下 父类无法操纵子类 但是 只有元类可以 在python中所有定义的类 都是type类的实例 在python 中另类定义 方法 class = type(classname, superclasses, attributedict) 这里 就是调用type的__call__运算符重载 并且会进一步调用 type.__new__(typeclass, classname, superclasses, attributedict) type.__init__(class, classname, superclasses, attributedict) """ class foo(type): def __new__(cls, *args, **kwargs): """ 本质上如果 当前类被指定成 metaclass 则 先创建自己 """ # print(*args) # print(**kwargs) print("in foo new cls.__name__", cls.__name__) a = type.__new__(cls, *args, **kwargs) print("in foo new a", a) return a def __init__(self, *args, **kwargs): print("in foo init self.__name__11", self.__name__) super(foo, self).__init__(*args, **kwargs) def __call__(cls, *args, **kwargs): """ 本质上 调用当前类的__new__ 在调用类的__init__方法 将self替换成cls """ print("in foo call",cls.__name__) # call_obj=super(foo, cls).__call__(*args, **kwargs) call_obj=cls.__new__(cls) cls.__init__(cls,*args,**kwargs) print("call",call_obj) return call_obj class bar(metaclass=foo): """ 若此类本身或者父类继承了metaclass 则必须要用metaclass 来创建 """ def __init__(self): print("in bar init") def __new__(cls, *args, **kwargs): print("__bar new") return object.__new__(cls) # 其实通过上述 # metaclass 的 __new__ __init__是用来控制类的生成的 # __call__是用来控制 类的实例生成的 因为在__call__中可以控制子类的__new__ __init__ # bar() # bar_cls=foo('barobj',(object,),{}) # print(bar_cls) # class bast(bar): # """ # bast 继承了bar 所以会调用metaclass来创建 # """ # pass #obj = bar # obj2=bast() """ 类由type来创建 class foo(metaclass=type): pass 继承type class foo(type): pass """ class foo(object): pass #print(type(foo)) # # # # obj 这个实例对象 是类 foo创建 # obj = foo() # # # foo这个类是由type创建的 python 里一切皆对象 # foo1 = type('foo1', (object,), {})