python-3.x 为什么不能在__setattr__中为属性赋值{attr:value}?

rnmwe5a2  于 2023-08-08  发布在  Python
关注(0)|答案(1)|浏览(75)

我们可以使用{attr:value}来分配属性:

class Room():
    pass

字符串
创建类Room的示例:

r=Room()


指定属性name

r.__dict__ = {'name':'r1'}
r.name
'r1'


重写Room类:

class Room:
    def __init__(self,name):
        self.name = name
    def __setattr__(self,attr,value):
        self.__dict__ = {attr:value}


创建示例:

r=Room('r1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
  File "<stdin>", line 5, in __setattr__
  File "<stdin>", line 5, in __setattr__
  File "<stdin>", line 5, in __setattr__
  [Previous line repeated 994 more times]
RecursionError: maximum recursion depth exceeded


我可以用self.__dict__[attr]=value修复它,但我想知道为什么不能在__setattr__中以self.__dict__ = {attr:value}分配属性?

tvokkenx

tvokkenx1#

因为__dict__是一个属性,所以self.__dict__ = ...会调用__setattr__,这会导致无限递归。如错误所示。
如文件所述:
如果__setattr__()想要赋值给示例属性,它应该调用同名的基类方法,例如object.__setattr__(self, name, value)
然后你的代码变成:

...
    def __setattr__(self,attr,value):
        object.__setattr__(self, '__dict__', {attr:value})

字符串
我的建议是:不要乱用__setattr__(在真实的的代码中),除非你真的必须知道你在做什么(对于__dict__也是一样)。通常有比使用__setattr__更好的方法来获得您想要的实际代码。

相关问题