鱼C论坛

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

[已解决]第46课 课上的循环看不懂

[复制链接]
发表于 2020-12-22 01:20:44 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 17623095765 于 2020-12-22 13:29 编辑
# p12_5.py
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)

    def getArea(self):
        return self.width * self.height
>>>r1=Rectangle(4,5)
>>>r1.getArea()
20
>>>square=10
当square=10时,触发__setattr__,调用if里面的 self.width=value,也就是r1.width=10,这里出现‘=’,那么应该调用__setattr__,因为‘name’==‘square’,然后无限递归下去。
但是不会,不知道哪里错了。
最佳答案
2020-12-22 10:19:11
本帖最后由 小伤口 于 2020-12-22 10:20 编辑
>>> r1=Rectangle(4,5)
>>> r1.getArea()
20
>>> r1.square=10
>>> r1.getArea()
100
>>> 
这样调用才会触发__setattr__,
square=10这样不过是普通赋值而已
话说你用的是 r1=Rectangle(4,5)
为什莫 你写成 r.getArea()这样也能出结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-12-22 10:19:11 | 显示全部楼层    本楼为最佳答案   
本帖最后由 小伤口 于 2020-12-22 10:20 编辑
>>> r1=Rectangle(4,5)
>>> r1.getArea()
20
>>> r1.square=10
>>> r1.getArea()
100
>>> 
这样调用才会触发__setattr__,
square=10这样不过是普通赋值而已
话说你用的是 r1=Rectangle(4,5)
为什莫 你写成 r.getArea()这样也能出结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-22 13:32:36 | 显示全部楼层
小伤口 发表于 2020-12-22 10:19
这样调用才会触发__setattr__,
square=10这样不过是普通赋值而已
话说你用的是 r1=Rectangle(4,5)

魔法方法不是自动调用的吗? 因为改了__setattr__,那么我每次赋值应该都会触发__setattr__呀?
(那里打少了一个1,改过来了)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-12-22 14:04:36 | 显示全部楼层
17623095765 发表于 2020-12-22 13:32
魔法方法不是自动调用的吗? 因为改了__setattr__,那么我每次赋值应该都会触发__setattr__呀?
(那里打 ...

r1.square意思是调用Rectangle对象里的square
是让python分辨出你的square是普通的还是对象里面的
与魔法方法是自动调用的并不冲突
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-22 15:30:22 | 显示全部楼层
本帖最后由 17623095765 于 2020-12-22 15:35 编辑
小伤口 发表于 2020-12-22 10:19
这样调用才会触发__setattr__,
square=10这样不过是普通赋值而已
话说你用的是 r1=Rectangle(4,5)


为了方便,我加了步骤
class Rectangle:
    
    def __init__(self, width=0, height=0):
        print('执行__init__')
        
        self.width = width
        print('__init__中的self.width')
        
        self.height = height
        print('__init__中的self.height')


    def __setattr__(self, name, value):
        print('__setattr__被调用')
        
        if name == 'square':
            print('if正在被调用')
            
            self.width = value
            print('if中的self.width = value')
            
            self.height = value
            print('if中的self.height = value')
   
        else:
            print('else被调用')
            super().__setattr__(name,value)


    def getArea(self):
        print('getArea被调用')
        return self.width * self.height

是在r1.square=10就调用了__setattr__,在r1.square=10执行了第一次if后  为什么第二次去执行了else?,这个时候name还是square呀?
>>> r1=Rectangle(4,5)
执行__init__
__setattr__被调用
else被调用
__init__中的self.width
__setattr__被调用
else被调用
__init__中的self.height

>>> r1.getArea()
getArea被调用
20

>>> r1.square=10
__setattr__被调用
if正在被调用
__setattr__被调用
else被调用
if中的self.width = value
__setattr__被调用
else被调用
if中的self.height = value

>>> r1.getArea()
getArea被调用
100
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-22 15:42:43 | 显示全部楼层
小伤口 发表于 2020-12-22 14:04
r1.square意思是调用Rectangle对象里的square
是让python分辨出你的square是普通的还是对象里面的
与魔 ...

我明白了  第二次是self.width = value  也就是r1.width=10
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-12-22 16:37:27 | 显示全部楼层
17623095765 发表于 2020-12-22 15:42
我明白了  第二次是self.width = value  也就是r1.width=10

可以这么理解,可惜你码这么多字了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-17 01:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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