233倔强不秃 发表于 2020-3-12 12:14:36

__setattr__(),__delattr__()触发死循环的问题

在执行以下程序时,陷入死循环:
class Rectangle:
    def __init__(self, width=0,height=0):
      self.width = width
      self.height = height

    def __setattr__(self,name,value):
      if name == 'square':
            self.width = value
            self.height = value
      else:
            self.name = value
            
    def getArea(self):
      return self.width * self.height

r1 = Rectangle(3,4)


r2 = Rectangle()
r2.square = 5

print(r1.getArea())
print(r2.getArea())


分析:
self.name = value 本句会出现死循环,因为在实例化对象时,init()构造器内部赋值操作会除法__setattr__方法,当执行到self.name = value时,赋值行为会触发__setattr__函数,然后会继续执行函数里的代码,继而再次触发__setattr__函数,这就成了一个不可解的死循环。
解决方法有如下两种:
方法①:我们去调用系统写好的基类,系统的总是最安全的!super()可以帮你找到所有函数的父类,在元素没有基类的情况下super()函数会默认为python的object类;
方法②:__dict__它的作用是以字典的属性显示出当前对象的所有属性以及对应的值!比如:{‘width’: 3};
同样的,getattribute:是定义该属性被访问时的方法,delattr:定义属性被删除时的方法。
按照上面方式重写方法时,__getattribute__会一直获得,__delattr__会一直删除而陷入死循环,而他们的解决方法,和上面写的一样,有两种方法,都可以选择使用。


问题疑惑:
请问为什么执行 if name == 'square':中的self.width = value 和 self.height = value 就不会再次触发__setattr__()函数?

zltzlt 发表于 2020-3-12 12:16:52

也会啊

233倔强不秃 发表于 2020-3-12 15:01:18

zltzlt 发表于 2020-3-12 12:16
也会啊

懂了,谢谢
页: [1]
查看完整版本: __setattr__(),__delattr__()触发死循环的问题