每当我做OOP时,“超出最大递归深度”

时间:2014-03-07 12:21:11

标签: python oop python-2.7 recursion

  File "C:\tv.py", line 20, in set_channel
    self.channel = new_channel
RuntimeError: maximum recursion depth exceeded

我正在尝试我的第一个OOP问题。我教科书中的问题是:

“通过将电视创建为对象来编写模拟电视的程序。允许用户增大/减小音量,并设置频道编号。确保频道和音量值保持在有效范围内。 “

我的问题是:

  1. 我的结构大致正确吗? (因为我选择制作inc / dec音量的方法等)

  2. 为什么我收到递归错误?我想这意味着我处于某种无限循环中,但我绝对看不到它。

  3. 我未完成的“解决方案”:

    # 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.")
    

2 个答案:

答案 0 :(得分:6)

您的媒体资源与您尝试使用该媒体资源访问的网址名称相同。因此,当您访问它时,它会递归地尝试获取它自己的值。

重命名属性应该解决它。

将代码更改为:

channel = 0
Channel = property(get_channel, set_channel)

将阻止递归发生。您将Channel作为属性(因此请调用此属性),该属性使用get / set_channel方法访问channel字段。

此属性的分配也不适用于sony.channel(3)。您必须像其他任何值一样实际分配给该属性:

sony.channel = 3

或(如果您已经更改了财产问题)

sony.Channel = 3

虽然这不会阻止您稍后使用该卷的问题。 self.volume未被声明为字段(或作为该事项的属性),并且inc / dec_volume函数中的get_volume也是如此。

答案 1 :(得分:1)

问题出现在这里:

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)

self.channel的每个requet都运行get_channel(),但get_channel()请求self.channel,依此类推。

要避免这种情况,您需要创建一个helper-variable,它将存储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