请建议如何自定义Python切片
我有一个类,它是列表对象的子类。现在我需要处理切片操作。根据我在网上看到的资料,这个操作需要用到 __getitem__
方法。至少在我使用的 Python 2.7+ 版本中是这样。我已经实现了这个方法(见下面的代码),但是当我传入一个切片时,__getitem__
方法并没有被调用。相反,程序直接进行了切片操作,并返回了一个列表。我希望能返回我自己定义的 myList 的新实例。
请帮我找出问题出在哪里。
谢谢!
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]
1 个回答
17
请查看这个说明:
object.__getslice__(self, i, j)
从2.0版本开始,这个功能被弃用了:支持切片对象作为
__getitem__()
方法的参数。(不过,CPython中的内置类型目前仍然实现了__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)