Python中以双下划线 "__" 表示类的私有成员或方法(实际上不存在私有,可以通过名字直接访问),Python内建一些类成员方法。
1、查看所有类内建方法:
class TmpCls :
pass
print(dir(TmpCls))
2、__new__与__init__方法:
class TmpCls :
def __init__(self) :
print('call __init__')
#__new__目的:实例化一个对象。
# 参数:方法需要一个代表着要实例化的类 cls 。
# 返回:需要返回一个实例,所以需要有返回值。
def __new__(cls, *args, **kwargs) :
print('call __new__')
return object.__new__(cls)
tmp = TmpCls()
3、__class__方法: __class__与type()函数类似,均是查看实例对应的类
class TmpCls :
def __init__(self) :
print('call __init__')
#__new__目的:实例化一个对象。
# 参数:方法需要一个代表着要实例化的类 cls 。
# 返回:需要返回一个实例,所以需要有返回值。
def __new__(cls, *args, **kwargs) :
print('call __new__')
return object.__new__(cls)
tmp = TmpCls()
print(tmp.__class__)
print(type(tmp))
print(TmpCls.__class__) #输出type,类TmpCls本身就是type的实例
print(type(TmpCls))
4、__getattr__ __getattrbute__ __dict__方法: 先来看两个现象
class TmpCls :
def __init__(self) :
self.key1 = 'value_init_key1'
self.key2 = 'value_init_key2'
def __getattribute__(self, name) :
if name == 'key1' :
return 'value_bute_key1'
raise AttributeError()
def __getattr__(self, name) :
if name == 'key1' :
return 'value_attr_key1'
elif name == 'key2' :
return 'value_attr_key2'
elif name == 'key3' :
return 'value_attr_key3'
tmp = TmpCls()
print(tmp.key1, tmp.key2, tmp.key3, tmp.key4)
最终输出:value_bute_key1 value_attr_key2 value_attr_key3 None
class TmpCls :
def __init__(self) :
self.key1 = 'value_init_key1'
self.key2 = 'value_init_key2'
"""def __getattribute__(self, name) :
if name == 'key1' :
return 'value_bute_key1'
raise AttributeError()"""
def __getattr__(self, name) :
if name == 'key1' :
return 'value_attr_key1'
elif name == 'key2' :
return 'value_attr_key2'
elif name == 'key3' :
return 'value_attr_key3'
tmp = TmpCls()
print(tmp.key1, tmp.key2, tmp.key3, tmp.key4)
最终输出:value_init_key1 value_init_key2 value_attr_key3 None
导致不同结果的现象在于,如果没有重写 __getattrbute__,变量搜寻方式:__dict__ -> __getattr__
如果重写了__getattrbute__,搜寻方式:__getattrbute__,在该方法中,若未找到则直接结束,若未找到却不想直接结束,可以跑出异常 raise AttrButeError(),跑出异常后,会调用 __getattr__