鱼C论坛

 找回密码
 立即注册
查看: 1075|回复: 6

[已解决]关于setattr的疑惑

[复制链接]
发表于 2020-6-23 20:30:31 | 显示全部楼层 |阅读模式

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

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

x
class Rectangle:
    def __init__(self,width=0,height=0):
#发生赋值操作则会自动触发__setattr__(r1,width,0)
        self.width=width
        self.height=height
#赋值会触发setattr;else语句中的self.name会出现自动递归的情况
    def __setattr__(self,name,value):
        if name=='square':
            self.width=value
            self.height=value
        else:
           super().__setattr__(name,value)#super()就是self参数不用写在括号里
#获得面积
    def getArea(self):
        return self.width*self.height
            

我想问一下在整个__setattr__的方法中的else语句里面,是小甲鱼课堂上已经做过修改的之后的代码改之前这一句是:self.time=value错误的原因是:发生赋值操作自动会触发__setattr__于是就陷入了无限的递归。我想问一下在该方法下面的if语句下面还有一个self.width,self.height的赋值操作为什么这两个语句就不用担心会触发该方法再无限递归下去呢?
最佳答案
2020-6-24 09:20:50
波大大12138 发表于 2020-6-24 09:03
这里我其实想问的是:在__init__方法里面如果初始化了一个变量就叫做'square',那么在下面执行setattr的 ...

不会啊,你其实如果理解了我上面的例子,你就会理解这个

当你初始化了一个变量叫 square ,会自动调用  __setattr__方法  if 判断条件成立,赋值 :
self.width = value
self.height = value


然后其实赋值 就是赋值了 self.width,self.height 重新调用  __setattr__方法,这次 因为  name 都不为 square 所以执行else ,就成功赋值了呀?

不会无限递归,你先理解好我 4 L 的,自然会理解这个
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-6-23 20:31:04 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

发表于 2020-6-23 20:45:36 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-23 20:57:17 | 显示全部楼层


首先 __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__ 方法



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

使用道具 举报

 楼主| 发表于 2020-6-24 09:03:40 | 显示全部楼层
Twilight6 发表于 2020-6-23 20:57
首先 __init__ 方法里面有两个赋值操作:

这里我其实想问的是:在__init__方法里面如果初始化了一个变量就叫做'square',那么在下面执行setattr的时候if语句就成立了就会执行self.width和self.height的赋值操作那么这又会重新调用setattr陷入无限递归了,这是怎么回事呢,不会出错吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-24 09:13:51 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-24 09:20:50 | 显示全部楼层    本楼为最佳答案   
波大大12138 发表于 2020-6-24 09:03
这里我其实想问的是:在__init__方法里面如果初始化了一个变量就叫做'square',那么在下面执行setattr的 ...

不会啊,你其实如果理解了我上面的例子,你就会理解这个

当你初始化了一个变量叫 square ,会自动调用  __setattr__方法  if 判断条件成立,赋值 :
self.width = value
self.height = value


然后其实赋值 就是赋值了 self.width,self.height 重新调用  __setattr__方法,这次 因为  name 都不为 square 所以执行else ,就成功赋值了呀?

不会无限递归,你先理解好我 4 L 的,自然会理解这个
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-20 07:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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