递归错误:超出最大递归深度python属性getter setter。

11 浏览
0 Comments

递归错误:超出最大递归深度python属性getter setter。

这个问题已经有答案了:

在Python类中使用属性会导致\"递归深度超出最大值\" [重复]

Python中@property装饰器是如何工作的?

我正在尝试在这个简单的类中进行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 
    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

admin 更改状态以发布 2023年5月21日
0
0 Comments

无论何时您在 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"

0
0 Comments

看起来由于name是一个属性,你使用get_nameset_name定义了它,当你调用self.name = n时,它实际上调用了属性的setter,即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)

0