Python-元类
1、旧式类VS新式类
在python范畴,一个类可以是两种类型之一。官方术语并没有对此进行区分,所以它们被非正式的称为旧式类和新式类。
旧式类:
对于旧式类,类(class)和类型(type)并不完全相同,一个旧式类的实例总是继承自一个名为instance的内置类型。如果obj是旧式类的实例,那么obj.class就表示该类,但type(obj)始终是instance类型。
新式类:
新式类统一了类(class)和类型(type)的概念,如果obj是新式类的实例,type(obj)则与obj.class相同
注意:在python2中,默认所有类都是旧式类,在python2.2之前,根本不支持新式类,从python2.2开始,可以创建新式类,但必须明确声明它为新式类。
在python3中,所有类都是新式类,因此,python3可以交换一个引用对象的类型和类。
2、类型(Type)和类(class)
什么是元类?
python中的任何新式类以及puthon 3中的任何类都是type元类的一个实例,函数type实际上是一个元类,type就是python在背后用来创建所有类的元类
注意区分元类和继承的基类
- type:是元类,所有的类都是通过type所创建出来的
- object:是顶层的基类,所以类的继承顶层父类都是object
3、使用type动态定义类
1 def func(self): 2 print('这是是func方法') 3 # type 创建类需要三个参数 4 # 第一个:类名 -->> str 5 # 第二个:继承的父类 -->> tuple 6 # 第三个:方法和属性 -->> dict 键值对的形式表示属性或对应的方法 7 Test = type('Test',(object,),{"attr":100,"__attr2":200,'function':func}) 8 9 t = Test() 10 t.function()
4、自定义元类
类的创建过程分析:
- 类的创建过程可以通过在定义metaclass关键字参数来指定创建类的元类
- 如果python没有找到metaclass,它会继续在父类中寻找metaclass,并尝试做和前面同样的操作,如果python在任何父类中都找不到metaclass,python就会用内置的type来创建这个类对象
1 # 自定义元类必须继承type 2 class MyClass(type): 3 """自定义元类,将类的所有属性名变为大写""" 4 5 def __new__(cls, name, bases, attr_dict, *args, **kwargs): 6 for i, y in list(attr_dict.items()): 7 # 删除原有key 8 attr_dict.pop(i) 9 # 修改key为大写 10 attr_dict[i.upper()] = y 11 return super().__new__(cls, name, bases, attr_dict) 12 13 # 通过自定义元类创建类 14 class Test(metaclass=MyClass): 15 name = 'm' 16 # 父类指定元类,子类可继承父类所指定的元类 17 class TestInfo(Test): 18 pass 19 20 print(type(Test)) # >>> <class '__main__.MyClass'> 21 print(Test.name) # >>> m 22 print(Test.__dict__)

浙公网安备 33010602011771号