2011-02-24 44 views
7

我有一個類的列表對象的子類。現在我需要處理切片。從我在interrtubes上閱讀的所有內容中,必須使用__getitem__方法完成。至少在Python 2.7+這是我正在使用的。我已經完成了這個(見下文),但是當我傳入一個片段時,不會調用__getitem__方法。相反,一個切片完成並返回一個列表。我想返回一個myList的新實例。自定義Python切片,請告知

請幫我發現什麼是錯的。

謝謝!

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] 

回答

17

參見this note

object.__getslice__(self, i, j)

自2.0版本不推薦使用:支持 切片對象作爲參數傳遞給 __getitem__()方法。 (然而,在CPython的內置類型目前 仍然實現__getslice__()因此,你必須覆蓋它 派生類實現 切片時。

所以,因爲你繼承list你必須覆蓋__getslice__,儘管它已被棄用

我認爲你應該通常避免subclassing builtins,有太多奇怪的細節。如果你只是想要一個行爲像一個列表的類,有一個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)