如何在 Python 中继承和扩展列表对象?

我对使用 python 列表对象感兴趣,但是功能稍有改动。特别是,我希望列表是1索引而不是0索引。例如:

>> mylist = MyList()
>> mylist.extend([1,2,3,4,5])
>> print mylist[1]

输出应为: 1

但是,当我更改 __getitem__()__setitem__()方法来执行此操作时,我得到了一个 RuntimeError: maximum recursion depth exceeded错误。我对这些方法进行了很多修改,但基本上就是这样的:

class MyList(list):
def __getitem__(self, key):
return self[key-1]
def __setitem__(self, key, item):
self[key-1] = item

我想问题在于 self[key-1]本身调用的方法与它定义的方法相同。如果是这样,我如何使它使用 list()方法而不是 MyList()方法?我尝试使用 super[key-1]而不是 self[key-1],但这导致了投诉 TypeError: 'type' object is unsubscriptable

有什么想法吗? 如果你能为我指出一个很好的教程,这将是伟大的!

谢谢!

72524 次浏览

使用 super()函数调用基类的方法,或者直接调用该方法:

class MyList(list):
def __getitem__(self, key):
return list.__getitem__(self, key-1)

或者

class MyList(list):
def __getitem__(self, key):
return super(MyList, self).__getitem__(key-1)

但是,这不会改变其他列表方法的行为。例如,索引保持不变,这可能导致意外的结果:

numbers = MyList()
numbers.append("one")
numbers.append("two")


print numbers.index('one')
>>> 1


print numbers[numbers.index('one')]
>>> 'two'

相反,子类整数使用相同的方法来定义所有数字,使它们从设置的值减去1。瞧。

对不起,我必须这么做。这就像微软把黑暗定义为标准的笑话。

通过创建从 collections.MutableSequence继承的类,可以避免违反 Liskov代换原则collections.MutableSequence是一个抽象类。它看起来像这样:

def indexing_decorator(func):
def decorated(self, index, *args):
if index == 0:
raise IndexError('Indices start from 1')
elif index > 0:
index -= 1
return func(self, index, *args)
return decorated




class MyList(collections.MutableSequence):
def __init__(self):
self._inner_list = list()


def __len__(self):
return len(self._inner_list)


@indexing_decorator
def __delitem__(self, index):
self._inner_list.__delitem__(index)


@indexing_decorator
def insert(self, index, value):
self._inner_list.insert(index, value)


@indexing_decorator
def __setitem__(self, index, value):
self._inner_list.__setitem__(index, value)


@indexing_decorator
def __getitem__(self, index):
return self._inner_list.__getitem__(index)


def append(self, value):
self.insert(len(self) + 1, value)
class ListExt(list):
def extendX(self, l):
if l:
self.extend(l)