class my_meta(type):
def __init__(self, *args):
print('__init__')
def __call__(self, *args, **kwargs):
print('__call__')
return super(my_meta, self).__call__()
def __new__(cls, *args, **kwargs):
print('__new__')
return super(my_meta, cls).__new__(cls, *args, **kwargs)
class T(metaclass=my_meta):
def __init__(self):
print("init")
pass
def __call__(self, *args, **kwargs):
print("call")
def __new__(cls, *args, **kwargs):
print("new")
return super().__new__(cls, *args, **kwargs)
def __setattr__(self, key, value):
print('setattr')
super(T, self).__setattr__(key, value)
def __getattr__(self, item):
print('getattr')
return self.__dict__.get(item)
def __setitem__(self, key, value):
print('setitem')
super(T, self).__setattr__(key, value)
def __getitem__(self, item):
print('getitem')
return self.__dict__.get(item)
def __getattribute__(self, item):
print('get_attribute')
return super(T, self).__getattribute__(item)
if __name__ == '__main__':
t = T()
print('-' * 90)
t.name = 'z'
t['nn'] = 'nn'
print(t.nn)
print('x'*99)
print(t.nn)
print(t['nn'])
print('-' * 90)
print(t.z)
# print(t['z'])
程序运行结果为
__new__
__init__
__call__
new
init
------------------------------------------------------------------------------------------
setattr
setitem
get_attribute
nn
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
get_attribute
nn
getitem
get_attribute
nn
------------------------------------------------------------------------------------------
get_attribute
getattr
get_attribute
None
接下来来分析结果,首先,类是由元类(metaclass)创建的,当Python解释器运行到 class T时,会调用元类的__new__()来创建一个类,然后调用__init__()实例化对象,这个就是T类。当解释器执行到 t=T()时,类名加括号会调用元类的__call__()方法(因为T是由my_meta创建的,T是它的一个实例,实例加括号会调用它类的call方法),再调用类的__new__创建、__init__初始化并返回创建的实例,也就是t。
类实例的所有属性都会保存在__dict__中。
当使用 类实例.xx时(t.xx)会调用类的__getattribute__()函数,如果报错或者为找到则会继续调用getattr方法,xx会当作getattr函数的key参数传进去。
类实例['xx'](t['xx'])会调用getitem方法,参数与getattr一致,当未找到值时也调用__getattribute__方法。
使用赋值语句时(t['xx']='xx' \ t.xx=‘xxx')会调用对应的set方法(setitem或setattr)setattr可调用父类的setattr来将值设置进去。