属性访问魔法方法中死循环的理解
>>> 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:
... self.name=value
... def getarea(self):
... return self.width*self.height
else下一句self.name=value,这里会在实例化对象时触发死循环,我大概能理解
但是if name=='square':下面的self.width=value,self.height=value,应该也会触发死循环吧,当square赋值时,触发__setattr__()魔法方法,执行self.width=value,self.height=value,这里执行会再次触发__setattr__()魔法方法。
可实际上没报错,这是为什么 你的理解是对的,这段代码中存在一个问题,它的确会导致无限递归,这是因为__setattr__方法会在尝试对属性进行赋值操作时被调用,如果在__setattr__方法内部再次对属性进行赋值,就会再次调用__setattr__ ,从而形成无限递归。
然而,这个代码块的行为可能取决于你使用的 Python 的具体版本或实现。在某些版本或实现中,这可能不会引发错误,因为 Python 有一些内部机制可能会防止这种无限递归。
然而,最佳的做法是避免这种情况的发生。如果你希望在设置属性值时执行某些操作,你可以使用 property 装饰器来实现,而不是覆盖__setattr__ 。例如:
class Rectangle:
def __init__(self, width=0, height=0):
self._width = width
self._height = height
@property
def width(self):
return self._width
@width.setter
def width(self, value):
self._width = value
@property
def height(self):
return self._height
@height.setter
def height(self, value):
self._height = value
@property
def square(self):
return self._width * self._height
@square.setter
def square(self, value):
self._width = value
self._height = value
def getarea(self):
return self._width * self._height
在这个版本中,我使用了前导下划线的属性_width和_height来存储宽度和高度的值。当你尝试获取width 、 height或square的值时,会返回这些内部属性的值;当你尝试设置这些属性的值时,会更新内部属性的值,而不会引发无限递归。 isdkz 发表于 2023-6-19 17:31
你的理解是对的,这段代码中存在一个问题,它的确会导致无限递归,这是因为__setattr__方法会在尝试对 ...
回答的好详细呀,还给出了解决办法
非常感谢 isdkz 发表于 2023-6-19 17:31
你的理解是对的,这段代码中存在一个问题,它的确会导致无限递归,这是因为__setattr__方法会在尝试对 ...
wc
页:
[1]