为什么尝试通过 Python 属性设置 "points" 会导致无限递归?
Why does trying to set "points" via Python properties cause infinite recursion?
为什么尝试通过 Python 属性设置“点”会导致无限递归?
使用Python 3
import Task
myTask = Task.Task("Test",-5)
myTask.points = -7
print(myTask)
class Task:
def __init__(self,name="",points=0,times_done=0):
self.name = name
self.points = points
self.times_done = times_done
@property
def points(self):
return self.points
@points.setter
def points(self, points):
if (points < 0):
self.points = 0
else:
self.points = points
def __str__(self):
return "The task '" + self.name + "' is worth " + str(self.points) + " and has been completed " + str(self.times_done) + " times."
当它尝试用值 -5 构造它时(应通过 属性 将其设置为 0),它会在 setter 中的行 self.points = points
上无限递归 function/decoration @points.setter.
谢谢!
因为self.points = ...
调用了setter;在 setter 中,执行 self.points = ...
调用 setter;递归重复直到堆栈溢出。
通过使用其他名称,您可以防止递归:例如self._points
。
或者不使用 self.points = ...
,而是使用 self.__dict__['points'] = ..
(与 getter 相同):
@property
def points(self):
return self.__dict__['points']
@points.setter
def points(self, points):
if points < 0:
self.__dict__['points'] = 0
else:
self.__dict__['points'] = points
# self.__dict__['points'] = max(0, points)
那是因为在你的 property setter
里面,它再次调用自己:
@points.setter
def points(self, points):
if (points < 0):
self.points = 0 # call itself again here
else:
self.points = points # call itself again here
使用property
时需要另外一个字段来存储实际值,最好是"private" field
:
class Task(object):
def __init__(self,name="",points=0,times_done=0):
self.name = name
self.points = points
self.times_done = times_done
@property
def points(self):
return self._points
@points.setter
def points(self, points):
if (points < 0):
self._points = 0
else:
self._points = points
为什么尝试通过 Python 属性设置“点”会导致无限递归?
使用Python 3
import Task
myTask = Task.Task("Test",-5)
myTask.points = -7
print(myTask)
class Task:
def __init__(self,name="",points=0,times_done=0):
self.name = name
self.points = points
self.times_done = times_done
@property
def points(self):
return self.points
@points.setter
def points(self, points):
if (points < 0):
self.points = 0
else:
self.points = points
def __str__(self):
return "The task '" + self.name + "' is worth " + str(self.points) + " and has been completed " + str(self.times_done) + " times."
当它尝试用值 -5 构造它时(应通过 属性 将其设置为 0),它会在 setter 中的行 self.points = points
上无限递归 function/decoration @points.setter.
谢谢!
因为self.points = ...
调用了setter;在 setter 中,执行 self.points = ...
调用 setter;递归重复直到堆栈溢出。
通过使用其他名称,您可以防止递归:例如self._points
。
或者不使用 self.points = ...
,而是使用 self.__dict__['points'] = ..
(与 getter 相同):
@property
def points(self):
return self.__dict__['points']
@points.setter
def points(self, points):
if points < 0:
self.__dict__['points'] = 0
else:
self.__dict__['points'] = points
# self.__dict__['points'] = max(0, points)
那是因为在你的 property setter
里面,它再次调用自己:
@points.setter
def points(self, points):
if (points < 0):
self.points = 0 # call itself again here
else:
self.points = points # call itself again here
使用property
时需要另外一个字段来存储实际值,最好是"private" field
:
class Task(object):
def __init__(self,name="",points=0,times_done=0):
self.name = name
self.points = points
self.times_done = times_done
@property
def points(self):
return self._points
@points.setter
def points(self, points):
if (points < 0):
self._points = 0
else:
self._points = points