马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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:
super().__setattr__(name,value)#self.name=value会导致无限递归
def getArea(self):
return self.width*self.height
关于正方形的问题 小甲鱼说在init调用时触发了__setattr__的方法然后执行了else的语句
self.width=value 这里的value 是width的值吗 执行到这里不就已经可以结束了吗
为什么会陷入死循环呢??看解释说是又再次触发了setattr这个方法 怎么看出来的 没懂
还有就是基类的__setattr__方法是什么内容呢好像之前没有提到过诶
本帖最后由 Twilight6 于 2020-8-21 18:03 编辑
因为你不管执行 else 还是 if 代码块都有赋值操作,那么就会无限调用自身的 __setattr__ 方法
就好如你赋值调用了 __setattr__ , 结果进入 __setattr__ 方法后还是赋值操作,此时又调用自身,然后又是赋值操作又调用自身.....就永远没有出口了
去掉 else 里面的赋值操作,为什么不会陷入死循环呢?
首先 __init__ 方法里面有两个赋值操作:
self.width=width
self.height=height
此时假设你 实例化一个对象 r = Rectangle(5,100) 那么 __init__ 方法会自动执行:self.width = 5
self.height = 100
这两个赋值操作会调用直接的 __setattr__ ;先来看第一个 self.width=5 因为这里进行了赋值操作,所以调用了自己的 __setattr__ 方法
在 __setattr__ 方法中 name参数指的就是被赋值的变量名,简单说就是等号左边的,而这里就是指 width ,而 value 是等号右边的 就是你传入的 5
也就是你赋值 self.width=5 时候 name = 'width' 而 value = 5
__setattr__ 方法中首先进行判断变量名 是否为 square ,这里很显然 name = 'width' 不等于 'square' 所以执行 else
else 是用 super 调用基类的 __setattr__方法 来给 width 赋值为 'square' ,而不是调用自己的 所以不会调用自己的 __setattr__方法
同理 self.height=height 也是一样的 , 所以这样就不会导致 无限递归调用 __setattr__方法 的情况发生了,因为赋值操作到最后都是执行 父类的 __setattr__ 方法,而不是自己类的 __setattr__ 方法
在对一个属性设置值的时候,就会自动调到这个函数,每个设置值的方式都会进入这个方法,然后给对应变量设置对应的值。
|