Python类内建了__getattr__() / __setattr__() / __delattr__(),他们的具体含义以及调用时机?
先看__setattr__()和__getattr__() :
class TmpCls :
def __init__(self, name, age, sex, action) :
print('__init__')
self.name = name
self.age = age
self.sex = sex
self.action = action
def __setattr__(self, key, value) :
print('__setattr__', key, value)
#self.key = value #不能这样赋值,因为这样还是调用TmpCls.__setattr__,就是死递归
self.__dict__[key] = value #赋值实际就是在__dict__中增加
def __getattr__(self, key) :
print('__getattr__', key)
return self.__dict__.get(key, None)
tmp = TmpCls('xiaoming', 25, 1, '吃午饭')
print(tmp.__dict__)
print(tmp.name, tmp.other) #先调用__dict__,未找到才去__getattr__
上图中,关于__dict__和__getattr__()调用顺序的问题,有疑惑可以看我上一篇文章 :点这里
根据输出结果,可以发现,__setattr__的调用时机,是在我们对变量进行初始化赋值的时候,实际上这么说也不太准确,应该是在我们将变量插入__dict__容器中的时候。因为为了防止死递归,我们在__setattr__()中的操作,还是直接写入__dict__容器中。
然后继续看__delattr__ :
class TmpCls :
def __init__(self, name, age, sex, action) :
print('__init__')
self.name = name
self.age = age
self.sex = sex
self.action = action
def __setattr__(self, key, value) :
print('__setattr__', key, value)
#self.key = value #不能这样赋值,因为这样还是调用TmpCls.__setattr__,就是死递归
self.__dict__[key] = value #赋值实际就是在__dict__中增加
def __getattr__(self, key) :
print('__getattr__', key)
return self.__dict__.get(key, None)
def __delattr__(self, key) :
print('__delattr', key)
self.__dict__.pop(key)
tmp = TmpCls('xiaoming', 25, 1, '吃午饭')
print(tmp.__dict__)
print(tmp.name, tmp.other) #先调用__dict__,未找到才去__getattr__
del tmp.action
print(tmp.action)
print(tmp.__dict__)
tmp2 = TmpCls('xiaoli', 23, 0, '睡觉')
print(tmp2.__dict__)