Python中__getattr__、__setattr__、__delattr__具体做了什么事?调用时机?

        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__

Python中__getattr__、__setattr__、__delattr__具体做了什么事?调用时机?_第1张图片

上图中,关于__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__)

Python中__getattr__、__setattr__、__delattr__具体做了什么事?调用时机?_第2张图片

你可能感兴趣的:(python)