wbzxz 发表于 2023-6-21 22:49:49

关于魔法方法重复调用的问题。

>>> class C:
        def __setattr__(self, name, value):
                self.name = value

               
>>> c = C()
>>> c.x = 2
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
    c.x = 2
File "<pyshell#19>", line 3, in __setattr__
    self.name = value
File "<pyshell#19>", line 3, in __setattr__
    self.name = value
File "<pyshell#19>", line 3, in __setattr__
    self.name = value

RecursionError: maximum recursion depth exceeded

听了小甲鱼老师的课程,上面的代码会出现重复调用的错误,听了几遍好像理解了,请老师指点看看我的思路对吗?

1. 首先C类对象重写了__setattr__方法,并且方法中使用了“对象.属性名 = 值” 的语句(这条语句会触发调用 __setattr__ 方法)

2. 当输入 c.x = 2 时(使用“对象.属性名 = 值” 的写法 ),这时候就调用了被重写的 __setattr__ 方法,由于该方法被重写后,还是用了 “对象.属性名 = 值”的语句,这样又重新开始了C对象__setattr__ 方法的调用,从而造成了无限循环错误。

3. 小甲鱼老师说可以super()函数进行处理,请问下面的代码写法标准吗?

>>> class C:
        def __setattr__(self, name, value):
                super().__setattr__(name, value)

               
>>> c = C()
>>> c.x = 2
>>> c.x
2

歌者文明清理员 发表于 2023-6-21 22:52:32

你的理解是正确的。在重写 __setattr__ 方法时,如果要对属性赋值,应该调用父类的 __setattr__ 方法以避免无限递归。

而你使用了 super() 函数来实现这个目的,这是标准的用法。其中 super().__setattr__(name, value) 是调用父类的 __setattr__ 方法,将属性名和属性值作为参数传递给它。这样就可以正确地为对象的属性赋值了,而不会造成递归错误。
页: [1]
查看完整版本: 关于魔法方法重复调用的问题。