本文主要是介绍元类的介绍和元类创建类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【一】什么是元类
元类是所有类的基类,包括object
class Solution:... print(type(Solution)) # <class 'type'> print(type(dict)) # <class 'type'> print(type(object)) # <class 'type'> data = {'username':'dream'} print(type(data)) # <class 'dict'>
【二】直接使用type生成
【1】直接用关键字创建
正常创建类的方式 class 类名():类体代码
【2】直接使用 type 生成
类名 = type('类名',(父类1,父类2),名称空间字典)
class Student(object):... print(Student) # # <class '__main__.Student'> Student = type('Student',(object,),{'name':'knight'}) print(Student) # <class '__main__.Student'> print(type(Student)) # <class 'type'> # 如果是类的名称空间字典,一定会看到出来自己定义的属性以外的很多属性,这是自带的属性 # 如果是对象的名称空间字典,一定会只有__init__初始化后的属性 print(Student.__dict__) # {'name': 'knight',
【三】元类的使用
元类可以在创建类的过程中进行修改和增加
# 控制当前类名必须首字母大写!首字母不大写就报错! # 【1】创建元类 class MyType(type):def __init__(cls,class_name,class_bases,class_name_space):# cls 是当前类的本身print(f'cls:{cls}') # cls:<class '__main__.MyClass'># class_name 是当前类的类名# 首字母必须大写其他必须小写,否则报错print(f'class_name:{class_name}') # class_name:MyClassif not class_name.istitle():raise TypeError(f"首字母必须大写")# class_bases 当前类的父类print(f'class_bases:{class_bases}') # class_bases:()# class_name_space 当前类的名称空间print(f'class_name_space:{class_name_space}') # class_name_space:{'__module__': '__main__', '__qualname__': 'MyClass'}super().__init__(class_name,class_bases,class_bases) # 【2】创建一个继承元类的类 # metaclass 指定元类 class MyClass(metaclass=MyType):... class student(metaclass=MyType):...
【四】元类的进阶使用
class MyType(type):def __init__(cls, class_name, class_bases, class_name_space):super().__init__(class_name, class_bases, class_name_space) # 3.触发元类中的__call__def __call__(self, *args, **kwargs):# 4.打印三个参数# 当前类本身print(f"{self}") # <class '__main__.MyClass'># 类实例化的时候传进来的位置参数print(f"{args}") # ('knight',)# 类实例化的时候传进来的关键字参数print(f"{kwargs}") # {'age': 22}print(f"类名()触发MyType中的__call__") # 类名()触发MyType中的__call__# 加了这个判断,下面就必须使用关键字传参if args:raise TypeError(f"必须通过关键字传参数")# 5.如果不返回值就默认输入none# 一定要返回一个对象 ,直接把type拿过来用# 所以用super().__call__()# super() 其实就是typeobj = super().__call__(*args, **kwargs)print(f"obj:{obj}") # obj:<__main__.MyClass object at 0x00000140C105FD90># 6.返回当前对象return obj # 1.触发MyType的__init__方法 class MyClass(metaclass=MyType):def __init__(self, name, age):self.name = nameself.age = age def __call__(self, *args, **kwargs):print(f"myclass的对象()触发了__call__") # 2.对象(参数)调用,一定会触发MyType的__call__方法 # 7. me 接收的就是MyType的 __call__ 方法返回的obj对象 me = MyClass(name='knight', age=22) # 因为上面加了判断,这里就不能只写'knight',要改为name='knight',否则报错 print(me()) # myclass的对象()触发了__call__ print(me.name) # knight
总结
如果你想高度定制类的生产过程,那么编写元类里面的__init__
方法
如果你想高度定制对象的生产过程,那么编写元类里面的__call__
方法
这篇关于元类的介绍和元类创建类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!