鱼C论坛

 找回密码
 立即注册
查看: 1491|回复: 2

[已解决]__setattr__(),__delattr__()触发死循环的问题

[复制链接]
发表于 2020-3-12 12:14:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在执行以下程序时,陷入死循环:
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__()函数?
最佳答案
2020-3-12 12:16:52
也会啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-3-12 12:16:52 | 显示全部楼层    本楼为最佳答案   
也会啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-12 15:01:18 | 显示全部楼层

懂了,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-27 08:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表