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,), {})

浙公网安备 33010602011771号