超出最大递归深度,覆盖UserList下新类中的方法

时间:2013-09-13 16:36:55

标签: python class recursion iterator override

我正在UserList中创建一个新类,并尝试覆盖添加,追加和扩展方法,以便不会通过任何这些操作将重复值添加到列表中。到目前为止,我已经开始尝试覆盖append方法,当我尝试在对象上实现类时,我得到错误:超出了最大递归深度。这是我到目前为止所做的:

from collections import UserList

class UList(UserList):
  def append(self,item):
      for s in self:
          if item == s:
              print ("Item already exists in list")
          else:
              self.append(item)


x = [1,2,3,4,5]
z = UList(x)
print (z)
z.append(1)

2 个答案:

答案 0 :(得分:2)

你以递归方式调用相同的方法,调用baseclass的append方法来阻止无限递归:

Py2.x:

super(UList, self).append(item)

Py3.x:

super().append(item)

使用in运算符而不是遍历整个列表来检查项目是否存在。

from collections import UserList

class UList(UserList):
  def append(self, item):
      if item in self:
          print ("Item already exists in list")
      else:
          super(UList, self).append(item) # just `super().append(item)` in py3.x

答案 1 :(得分:1)

好吧,想一想。你已经在self.append()了。然后你打电话给self.append()。这是一个递归,下一次通过代码,没有任何改变(项目仍然没有在列表中),所以你再次递归然后再次,然后再次,最终,Python用完了堆栈用于存储递归状态的空间,您将收到错误。

请勿致电self.append()。您必须调用基类方法,因为您的无法执行追加。

def append(self, item):
    for s in self:
        if item == s:
            print ("Item already exists in list")
        else:
            UserList.append(self, item)

您也可以使用super(),但在这种情况下并非绝对必要; super()在多继承场景中至关重要,但在更简单的情况下,我发现显式调用基类更清晰。

另一点是迭代整个列表以查看您的项目是否在其中是浪费时间。而只是做:

def append(self, item):
    if item in self:
        print("Item already exists in list")
    else:
        UserList.append(self, item)

您可能还会重新考虑在append()方法中打印错误。引发异常会更好,以便使用您的类的代码可以检测错误并根据需要处理它。您还可以使错误消息更具描述性,以便找到重复项目。

def append(self, item):
    if item in self:
        raise ValueError(repr(item) + " already exists in list")
    else:
        UserList.append(self, item)

如果您不需要维护订单,也可以考虑使用set()。它不存储重复项,因此您只需添加项目即可获得重复项;你不必先检查。