2014-03-07 2 views
2
File "C:\tv.py", line 20, in set_channel 
    self.channel = new_channel 
RuntimeError: maximum recursion depth exceeded 

첫 OOP 문제를 시도하고 있습니다. 내 교과서의 문제는 다음과 같습니다 :OOP를 할 때마다 '최대 재귀 깊이 초과'

"개체를 만들어서 텔레비전을 시뮬레이트하는 프로그램을 작성하십시오. 사용자가 볼륨을 높이거나 낮추고 채널 번호를 설정할 수있게하십시오. 채널 및 볼륨 값을 확인하십시오. 유효한 범위 내에서 머물러 라. "

내 질문은 :

  1. 내 구조가 광범위하게 맞습니까? (inc/dec 볼륨 등의 메소드를 만들기 위해 선택했습니다)

  2. 왜 재귀 오류가 발생합니까? 나는 그것이 내가 어떤 종류의 무한 루프에 있음을 의미한다고 생각하지만, 나는 그것을 절대 볼 수 없다.

내 미완성 '솔루션'

# Television with Classes 
# User able to enter a channel number 
# and increase/decrease the volume 

class Television(object): 
    """A TV set.""" 
    def __init__(self, channel = 1, volume = 20): 
     self.channel = channel 
     self.volume = volume 

    def get_channel(self): 
     """Return current channel.""" 
     return self.channel 

    def set_channel(self, new_channel): 
     """Set the channel.""" 
     if 1 <new_channel> 5: 
      print "Invalid Channel. Must be between 1-5." 
     else: 
      self.channel = new_channel 

    channel = property(get_channel, set_channel) 

    def show_volume(self): 
     """Return current volume.""" 
     return self.volume 

    def inc_volume(self): 
     """Increase the volume by 1 unit.""" 
     if self.volume >= 20: 
      print "Volume is at maximum: ", get_volume, "\n" 
     else: 
      self.volume += 1 

    def dec_volume(self): 
     """Decrease the volume by 1 unit.""" 
     if self.volume <= 0: 
      print "Volume is at minimum: ", get_volume, "\n" 
     else: 
      self.volume -= 1 


sony = Television() 
print "Current channel: ", sony.channel 
print "Changing channel to 3..." 
sony.channel(3) 
print "Current channel: ", sony.channel 
print "Current volume: ", self.volume 
print "Increasing volume..." 
sony.inc_volume() 
print "Current volume: ", self.volume 

raw_input("\n\nPress enter to exit.") 
+0

'get_volume'방법은 어디에 있습니까? –

+0

@ SlavenTomac 나는 하나도 만들지 않았다. 나는 그것이 필요하다고 생각하지 않았다. – BBedit

답변

6

귀하의 속성은 속성에 액세스하려고하는 값과 동일한 이름을 가지고있다. 따라서 재귀 적으로 액세스 할 때 자신의 가치를 얻으려고합니다.

속성의 이름을 변경하면 해결됩니다.

이렇게 될 코드를 변경 :

channel = 0 
Channel = property(get_channel, set_channel) 

일이 일어나고에서 재귀를 중지합니다. get/set_channel 메소드를 사용하여 channel 필드에 액세스하는 속성으로 Channel 속성을 갖습니다 (그래서 이것을 호출합니다).

이 속성에 대한 할당은 sony.channel(3)에서도 작동하지 않습니다.

sony.Channel = 3 

이 문제를 멈추지 않을 것 '(이미 부동산 문제를 변경하는 경우)

sony.channel = 3 

나 : 당신은 실제로 다른 값 같은 속성에 할당해야합니다 나중에 볼륨을 가지고 있습니다. self.volume은 필드 (또는 해당 속성의 속성)로 선언되지 않으며 inc/dec_volume 함수에서 get_volume에 대해서도 동일하게 적용됩니다.

+1

줄을 바꿀 코드를 추가해야합니다. 어쨌든 내 +1을 얻었습니다 :) – Alfe

+0

@Alfe 어떻게'+ 1'을 윗 첨자에 넣었습니까?:) – thefourtheye

+0

@Alfe, 업데이트 된 답변을 참조하십시오. – ThaMe90

1

문제는 여기 낳는 : self.channel의

def get_channel(self): 
    """Return current channel.""" 
    return self.channel 

def set_channel(self, new_channel): 
    """Set the channel.""" 
    if 1 <new_channel> 5: 
     print "Invalid Channel. Must be between 1-5." 
    else: 
     self.channel = new_channel 

channel = property(get_channel, set_channel) 

모든 requet 등등 get_channel()를 실행하지만, self.channel에 대한 get_channel() 요청하고있다.

이를 방지하려면 self.channel의 실제 값을 저장하는 도우미 변수를 만들어야합니다.

self.__channel = None # Field where self.channel will be really stored 

def get_channel(self): 
    """Return current channel.""" 
    return self.__channel 

def set_channel(self, new_channel): 
    """Set the channel.""" 
    if 1 <new_channel> 5: 
     print "Invalid Channel. Must be between 1-5." 
    else: 
     self.__channel = new_channel 

channel = property(get_channel, set_channel) # Public interface 
관련 문제