RecursionError:最大递归深度超出了python属性getter setter [重复]
Posted
技术标签:
【中文标题】RecursionError:最大递归深度超出了python属性getter setter [重复]【英文标题】:RecursionError: maximum recursion depth exceeded python property getter setter [duplicate] 【发布时间】:2021-10-14 13:44:44 【问题描述】:我正在尝试在这个简单的类中做 getter setter,
class Person:
def __init__(self, n):
self.name = n
def get_name(self):
return self.name
def set_name(self, n):
self.name = n
name = property(get_name, set_name)
p = Person('Lewis')
p.name = 'Philo'
看起来非常简单明了,但不知何故它不起作用,我错过了什么,帮助我找到我出错的理解。
我收到以下错误。
Traceback (most recent call last):
File "/Users/napoleon/python-play/oops/person.py", line 15, in <module>
p = Person('Lewis')
File "/Users/napoleon/python-play/oops/person.py", line 4, in __init__
self.name = n
File "/Users/napoleon/python-play/oops/person.py", line 10, in set_name
self.name = n
File "/Users/napoleon/python-play/oops/person.py", line 10, in set_name
self.name = n
File "/Users/napoleon/python-play/oops/person.py", line 10, in set_name
self.name = n
[Previous line repeated 994 more times]
RecursionError: maximum recursion depth exceeded
【问题讨论】:
更准确的副本:Using Properties in Python classes cause “maximum recursion depth exceeded” (duplicate) 【参考方案1】:似乎因为name
是一个属性,当您调用self.name = n
时使用get_name
和set_name
定义它实际上是调用属性的设置器,即set_name
。
当您初始化 Person 对象时,它会调用 __init__
,然后调用 set_name
,因为它有 self.name = n
行,同样的情况发生在 set_name
本身(因为它有相同的行)。
一个解决方案可能是创建一个_name
成员并在getter 和setter 中使用它。
在更复杂的情况下,您可以检查它是否没有保存您发送给 setter 的值,然后才在 setter 中更改成员的值。
class Person:
_name = None
def __init__(self, n):
self._name = n
def get_name(self):
return self._name
def set_name(self, n):
self._name = n
name = property(get_name, set_name)
【讨论】:
answer 是首选的详细解释。【参考方案2】:当你在 Python 中创建访问器和修改器时,你不应该对属性和属性使用相同的标签,所以你需要做的就是使用 _
来防止无限循环:
只需将self.name
替换为self._name
就可以了:
class Person:
def __init__(self, n):
self.name = n
def get_name(self):
return self._name
def set_name(self, n):
self._name = n
name = property(get_name, set_name)
p = Person('Lewis')
p.name = 'Philo'
print(p.get_name()) #prints "Philo"
【讨论】:
【参考方案3】:那是因为你的类中的代码正在运行一个无限循环。
class Person:
def __init__(self, n):
self.name = n
def get_name(self):
return self.name
def set_name(self, n):
self.name = n
name = property(get_name, set_name)
p = Person('Lewis')
p.name = 'Philo'
应该是:
class Person:
def __init__(self, n):
self.name = n
def get_name(self):
return self._name
def set_name(self, n):
self._name = n
name = property(get_name, set_name)
p = Person('Lewis')
p.name = 'Philo'
额外的_
是为了让您不会运行无限循环。请注意,每当您使用提供的代码设置或获取名称时,它将永远运行 set_name
或 get_name
,因为您在 getter 或 setter 方法中设置或获取名称。
例如,使用p.name = 'Philo'
,您正在运行setter 方法。但是,在 setter 方法中,您使用 self.name = n
一次又一次地调用 setter 方法,而使用 self._name = n
可以防止 Python 陷入无限循环。
【讨论】:
以上是关于RecursionError:最大递归深度超出了python属性getter setter [重复]的主要内容,如果未能解决你的问题,请参考以下文章
RecursionError:最大递归深度超出了python属性getter setter [重复]
RecursionError:重命名列条目后调用 Python 对象时超出最大递归深度