17623095765 发表于 2020-12-22 01:20:44

第46课 课上的循环看不懂

本帖最后由 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()这样也能出结果
{:10_245:}

17623095765 发表于 2020-12-22 13:32:36

小伤口 发表于 2020-12-22 10:19
这样调用才会触发__setattr__,
square=10这样不过是普通赋值而已
话说你用的是 r1=Rectangle(4,5)


魔法方法不是自动调用的吗? 因为改了__setattr__,那么我每次赋值应该都会触发__setattr__呀?
(那里打少了一个1,改过来了)

小伤口 发表于 2020-12-22 14:04:36

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

r1.square意思是调用Rectangle对象里的square
是让python分辨出你的square是普通的还是对象里面的
与魔法方法是自动调用的并不冲突

17623095765 发表于 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

17623095765 发表于 2020-12-22 15:42:43

小伤口 发表于 2020-12-22 14:04
r1.square意思是调用Rectangle对象里的square
是让python分辨出你的square是普通的还是对象里面的
与魔 ...

我明白了第二次是self.width = value也就是r1.width=10

小伤口 发表于 2020-12-22 16:37:27

17623095765 发表于 2020-12-22 15:42
我明白了第二次是self.width = value也就是r1.width=10

可以这么理解,可惜你码这么多字了{:10_256:}
页: [1]
查看完整版本: 第46课 课上的循环看不懂