魔法方法: getattr setattr delattr
@TOC
一、getattr
__getattr__
在访问类内属性的时候如果类包含此属性,不会调用此方法,即直接返回;如果类内没有此属性会自动调用此方法
下面通过一个例子加深理解:这里我们构建了一个类obj,他包含有一个属性name,当我们初始化之后我们想要得到age信息,但是类内没有此信息,于是我们从__getattr__
中进行搜索,在里面运行完后__getattr__
函数并没有返回值,所以输出为None;然后我们想要得到height信息,类内依旧没有此信息,我们再次进入__getattr__
函数,其中匹配到了height,并返回相应的值
注意:我们在输出height之后再次输出了age,此时有值了,为什么呢?这是因为我们第一次进入到getattr函数中时,运行了self.age=22,即将age变为类内属性了,所以第二次输出时就有值了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class obj (): def __init__ (self, value ): self.name = value def __getattr__ (self, key ): print (f"__getattr__{key} " ) self.age = 22 if key == "height" : return 178 a = obj("harry" ) print (a.name)print (a.age)print (a.height)print (a.age)''' harry __getattr__age None __getattr__height 178 22 '''
二、setattr
__setattr__
在设置类内属性的时候会自动调用此方法,即只要在类内出现self.xx=xxx
就一定会调用此方法
下面举一个例子,这里我们初始化了一个类,name=“harry”,由于在初始化时出现了self.name=value语句,因此进入到__setattr__
函数中,其中赋值方法在代码中给出,其中错误方法为self.name=value,这是因为调用这句话时又会再次调用__setattr__
函数,然后又会执行self.name=value进入无限死循环
注意:由于此时类已经有属性name了,所以不会执行__getattr__
函数了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class obj (): def __init__ (self, value ): self.name = value def __setattr__ (self, name, value ): print (f"set: {name} --{value} " ) self.__dict__[name] = value def __getattr__ (self, key ): print (f"get: {key} " ) a = obj("harry" ) print (a.name)a.name = "Potter" print (a.name)''' set: name--harry harry set: name--Potter Potter '''
三、delattr
__delattr__
删除类内属性的时候会自动调用此方法
有了__getattr__
和__setattr__
之后,这个方法就很好理解,直接看下面带吗
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class obj (): def __init__ (self, value, height ): self.name = value self.height = height def __setattr__ (self, name, value ): print (f"set: {name} --{value} " ) object .__setattr__(self, name, value) def __getattr__ (self, key ): print (f"get: {key} " ) def __delattr__ (self, key ): print (f"delete: {key} " ) object .__delattr__(self, key) a = obj("harry" , 178 ) del (a.name)print (a.name)''' set: name--harry set: height--178 delete: name get: name None '''