我有一个子类化列表对象。现在,我需要处理切片。从我在管间阅读的所有内容中,都必须使用该__getitem__方法来完成。至少在我使用的Python 2.7+中。我已经完成了此操作(请参阅下文),但是__getitem__当我传递切片时未调用该方法。相反,将完成切片并返回列表。我想要一个myList的新实例返回。
__getitem__
请帮助我发现问题所在。
谢谢!
class myList(list): def __init__(self, items): super(myList, self).__init__(items) self.name = 'myList' def __getitem__(self, index): print("__getitem__") if isinstance(index, slice): print("slice") return self.__class__( self[x] for x in range(*index.indices(len(self))) ) else: return super(myList, self).__getitem__(index) if __name__ == "__main__": print("\nI'm tesing out custom slicing.\n") N = 10 L = myList(range(N)) L3 = L[3] L02 = L[:2]
看到这个注释:
object.__getslice__(self, i, j) 从2.0版开始不推荐使用:支持将切片对象用作__getitem__()方法的参数 。(但是,CPython中的内置类型当前仍在实现__getslice__()。 因此,在实现切片时,必须在派生类中重写它。
object.__getslice__(self, i, j)
从2.0版开始不推荐使用:支持将切片对象用作__getitem__()方法的参数 。(但是,CPython中的内置类型当前仍在实现__getslice__()。 因此,在实现切片时,必须在派生类中重写它。
__getitem__()
__getslice__()
因此,因为您list已经继承了子类__getslice__,所以即使它已弃用,也必须覆盖它。
list
__getslice__
我认为您通常应该避免对内建函数进行子类化,因为有太多奇怪的细节。如果您只想要一个行为类似于列表的类,则可以使用ABC来帮助您:
from collections import Sequence class MyList(Sequence): def __init__(self, *items): self.data = list(items) def __len__(self): return len(self.data) def __getitem__(self, slice): return self.data[slice] s = MyList(1,2,3) # lots of free methods print s[1:2], len(s), bool(s), s.count(3), s.index(2), iter(s)