2013-09-24 26 views
9

我有下面的类:的Python - 物业从列表设置使最大递归深度超过

class vehicle(object): 
    def __init__(self, name): 
     self.name = name 
     self.kinds_list = ["tank", "car", "motorbike", "bike", "quad" ] 

    @property 
    def kind(self): 
     return self.kind 

    @kind.setter 
    def kind(self, x): 
     if x in self.kinds_list: 
      self.kind = x 
     else: 
      raise AttributeError('No attribute {0} found !'.format(y)) 

设置一种使最大递归深度超过又名堆栈溢出。

问:如何重新编写setter以使其仅与固定列表一起工作?

+1

你只想要某些允许的属性?也许你应该看看'__slots__',而不是......或者是__setattr__' ......也许如果你在段落中解释了你想实现的目标...... –

+5

你可以使用'self.kind = x'来实现setter再次调用setter?为底层属性和属性使用不同的名称。 – millimoose

+1

@JonClements尽管不是远程堆栈溢出的原因。你的建议在这个特定的情况下很有用,但是不会帮助OP在一般情况下正确使用'@ property'。 – millimoose

回答

18

你达到最大递归深度的原因是在你的setter中,你做self.kind = ...,递归调用同一个setter。您应该将该值存储为一些私有属性,只需将self.kind重命名为self._kind即可。

class vehicle(object): 
    def __init__(self, name): 
     self.name = name 
     self.kinds_list = ["tank", "car", "motorbike", "bike", "quad" ] 

    @property 
    def kind(self): 
     return self._kind 

    @kind.setter 
    def kind(self, x): 
     if x in self.kinds_list: 
      self._kind = x 
     else: 
      raise ValueError('{0} is an illegal kind of vehicle!'.format(y)) 

这并不像在其他语言中一个真正的私有属性,因为没有什么能阻止你访问my_vehicle._kind。按照python中的约定,所有以下划线开始的内容都是私有的,通常不应该在类之外触及。或者as they say:蟒蛇是为了同意成年人;)。

我也稍微修改了setter中的错误信息。

+0

应该可能使错误的'AttributeError'' ValueError'代替... –

+0

谢谢,修复。当您尝试访问'my_object.illegal_attribute'时,'AttributeError'的主要用途可能在'__getattribute__'内。 'ValueError'在这里似乎更合适。 –

+0

我只是学习,因为你现在最有可能知道。 私人属性是下一个要学习的话题。谢谢! –

相关问题