元编程
type元类构建类
type(name, bases, dict) -> a new type
,type的另一种使用方式- 使用type元类,构建一个新的类
class A():pass
等价于type('A',(object,),{})
- class 语句只是语法糖,本质调用的就是type元类
- 差别,使用class关键字为类注入的属性和type元类构建时为类注入的属性有所不同,但这影响很小
- 参数
- name,类对象的名称,只是给程序员看的字符串
- bases,元组,类对象的所有直接继承基类
- dict,字典,存放类对象的属性;Key为字符串,对应类对象的属性变量;vlaue为类属性对应的对象,可以是属性,也可以是方法
- 使用type元类,构建一个新的类
class B(type):
pass
C = type('C',(object,),{}) # namedtuple使用type元类构建
print(B.__dict__)
print(C.__dict__)
返回值
{'__module__': '__main__', '__doc__': None}
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'C' objects>, '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None}
元类继承测试一
- 类对象的产生必定使用其指定的元类,且会走指定元类的__new__方法
- 指定元类的__new__方法,必须调用type.__new__()方法
- 注意:因为__new__是静态方法,super().__new__()和type.__new__效果等同
此处存疑,类走指定元类的__new__方法,返回值为type.__new__,为什么type(A)返回<class ‘__main__.Meta’>
class Meta(type): # Meta继承自type元类,继承了type原类的能力
def __new__(cls,*args,**kwargs): # 静态方法,不会绑定self和cls
print(cls) # 返回当前类对象
print(args) # 元组(name,(),{}),参考type(name,(),{})
print(kwargs) # 没什么用
return type.__new__(cls,*args,**kwargs)
# return super().__new__(cls,*args,**kwargs),效果同上
# metaclass=Meta,设置构建A的原类为Meta;默认是type,但是被Meta截胡
# 类对象的产生必定使用其指定的元类,且会走指定元类的new魔术方法
# 此处指定的是Meta原类,且Meta.__new__必须返回type.__new__(cls,*args,**kwargs),否则type(A)返回'NoneType'
# 此处存疑,调用type.__new__(cls,*args,**kwargs),为什么会返回类对象,而不是类对象实例???
class A(metaclass=Meta):
id = 1000
def __init__(self):
print('A.init~~~~~~~~~~~~~~~~')
print('-' * 30)
print(type(Meta),Meta.__mro__)
print(type(A))
返回值
<class '__main__.Meta'>
('A', (), {'__module__': '__main__', '__qualname__': 'A', 'id': 1000, '__init__': <function A.__init__ at 0x000002191E192D90>})
{}
------------------------------
<class 'type'> (<class '__main__.Meta'>, <class 'type'>, <class 'object'>)
<class '__main__.Meta'>
元类继承测试二
class Meta(type): # Meta继承自type元类,继承了type原类的能力
def __new__(cls,name,bases,dict):
print(name) # 返回类对象名,字符串
print(bases) # 返回类对象基类,元组
print(dict) # 返回类属性,key为变量,value为对象,字典
return type.__new__(cls,name,bases,dict)
class A(metaclass=Meta):
id = 1000
def __init__(self):
print('A.init~~~~~~~~~~~~~~~~')
class B(A):
def __init__(self):
print('B.init***********')
def test(self):
print('test')
C = type('C',(B,),{'__init__':test}) # {'__init__':test} 等价 def __init__(self):print('test)
D = type('D',(Meta,),{}) # D类继承自Meta,相当于type的孙子类,也是元类
print('-' * 30)
print(type(B))
print(type(C),C(),C.__mro__)
print(type(D),D.__mro__)
返回值
A
()
{'__module__': '__main__', '__qualname__': 'A', 'id': 1000, '__init__': <function A.__init__ at 0x000002273CE32D90>}
B
(<class '__main__.A'>,)
{'__module__': '__main__', '__qualname__': 'B', '__init__': <function B.__init__ at 0x000002273CE32E18>}
C
(<class '__main__.B'>,)
{'__init__': <function test at 0x000002273CE329D8>}
------------------------------
<class '__main__.Meta'>
test
<class '__main__.Meta'> <__main__.C object at 0x000002273CE35940> (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
<class 'type'> (<class '__main__.D'>, <class '__main__.Meta'>, <class 'type'>, <class 'object'>)
总结
- type(元类 / 元类子孙类),返回type
class Meta(type):pass
–class A(metaclass=Meta)
,type(A)返回Meta- 且继承自A的类类型都是Meta
type(元类 / 元类子孙类),返回type
class Meta(type):pass
–class A(metaclass=Meta)
,type(A)返回Meta- 且继承自A的类类型都是Meta