鱼C论坛

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

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

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

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

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

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

  5.     def __setattr__(self,name,value):
  6.         if name == 'square':
  7.             self.width = value
  8.             self.height = value
  9.         else:
  10.             self.name = value
  11.             
  12.     def getArea(self):
  13.         return self.width * self.height

  14. r1 = Rectangle(3,4)


  15. r2 = Rectangle()
  16. r2.square = 5

  17. print(r1.getArea())
  18. 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
也会啊
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-12 12:16:52 | 显示全部楼层    本楼为最佳答案   
也会啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

懂了,谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-27 17:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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