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__)

 

posted @ 2021-03-13 18:07  铲屎官_a  阅读(56)  评论(0)    收藏  举报