2017-03-25 2 views
3

왜 파이썬 속성을 통해 "점"을 설정하려고하면 무한 재귀가 발생합니까? 왜 파이썬 속성을 통해 "점"을 설정하려고하면 무한 재귀가 발생합니까?

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으로 설정되어야한다), 그것은 무한 재귀 값으로 구축 시도합니다 파이썬 3

import Task 

myTask = Task.Task("Test",-5) 

myTask.points = -7 

print(myTask) 

사용

설정 기 기능/장식에 self.points = points 줄에 @points.setter.

고마워!

+1

오류를 재현 할 수 없습니다. 여기에 코드를 생략하고 있습니까? – Julien

+0

전혀 관련이 없어야하는 내용. 내가 편집 할 것이다 – Matt

+1

@Julien, OP는 Python 3.x를 사용해야한다. 'object'를 상속 받아 파이썬 2.x를 사용한다면'class Task (object)'를 재현 할 수 있습니다. – falsetru

답변

4

은 setter를 호출하기 때문에; setter를 호출하는 이 실행됩니다. 재귀는 스택 오버플로가 발생할 때까지 반복됩니다.

다른 이름을 사용하면 재귀를 방지 할 수 있습니다 (예 : self._points).

또는 대신 self.points = ...를 사용하는 self.__dict__['points'] = .. (게터에 대한 동일) 사용

@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) 
1

의 당신의 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 
관련 문제