引子
元类是什么:
元类实例化产生类,类实例化产生对象
元类是创造类的类 type
type创造类的函数为type(类名,父类们,名称空间)
名称空间可以由exec产生。
字符串=“
a=10
b=20
def fun():
print(func)
”
exec(字符串,{},namespace)
## 如何通过元类控制类的产生,以及类的对象的产生
关键
***init***方法控制类的产生
*** call方法控制对象的产生
首先要理解,继承于元类的类就是元类,他继承了元类的方法。那么该类也具有创造类的功能:
元类造类的过程:
类=type(类名,父类们,名称空间)
class Mymeta(type):#Meta 也是一个元类
即你可以把type替换为Mymeta
则Meta也有类=Meta(类名,父类们,名称空间)
被控制的类又是怎么一个构造呢:通过metaclass关键字来控制类的如下:
class Student(object,metaclass=Mymeta):
用那个Mymeta控制Student的产生,话说也就是Mymeta产生了Student
类=type(类名,父类们,名称空间)#Mymeta也是元类因此如下:
Student=Mymeta(类名,父类们,名称空间),创建Student这个类
,调用的是Mymeta的init方法()该方法如下:
class Mymeta(type):
'''
init第一个参数是你需要创建的一个类(Student),后面的三个参数是:类名,父类们,名称空间,因此
'''
def __init__(cls,类名,父类们,namespace(名称空间)):
print(cls)
'''
在此可以做创建类的操作,即控制类的创建,可以通过名称空间来控制一些属性
本质是调用元类的创建类的方法
'''
super().__init__(class_name,bases,namespace)
控制类名必须为驼峰体代码如下:
class Mymeta(type):
# 创建类调用
def __init__(cls,class_name,bases,namespace):
# if cls.__doc__==None:
# raise Exception("必须有注释dsb(大帅比)")
if not class_name.istitle():
raise Exception("必须是驼峰体sb(大帅比)")
#本质调用元类创造类的方法 super(Mymeta)
super().__init__(class_name,bases,namespace)###
class student(object,metaclass=Mymeta):
pass
如何控制类创建对象呢
本质是走的元类的__call__方法
类的对象的创建过程:
类名加()实例化,走的是元类的__call__(self,*args,**kwargs)方法
Student实例化走的是元类的__call__方法,不走自身的init方法
该元类控制生成的对象,会调用元类的call方法
在call中返回值就是创建的对象:
class Mymeta(type):
创建类调用
def __init__(cls,class_name,bases,namespace):
if cls.__doc__==None:
raise Exception("必须有注释dsb(大帅比)")
if not class_name.istitle():
raise Exception("必须是驼峰体sb(大帅比)")
if len(bases)==0:
raise Exception("父类必须明确")
实例化
super().__init__(class_name,bases,namespace)
def __call__(cls, *args, **kwargs):
print("call in run")
# 谁来创建对象开辟空间
obj=object.__new__(cls)
#obj.name=args[0]不能写死
#控制手段
obj.meta_name=cls.__name__
调回自己的init方法,cls调用自身方法
cls.__init__(obj, *args, **kwargs)
#return 123#创建对象得到的就是123
return obj
```
class Student(metaclass=Mymeta):
def __init__(self,name,age):
self.name=name
self.age=age
s=Student('wy',18)
print(s.meta_name)