2011-02-24 6 views
7

Tengo una clase que subclasifica el objeto list. Ahora necesito manejar el corte. De todo lo que leo en los intertubos, esto tiene que hacerse usando el método __getitem__. Al menos en Python 2.7+, que es lo que estoy usando. He hecho esto (ver más abajo), pero no se llama al método __getitem__ cuando paso una porción. En cambio, se realiza un corte y se devuelve una lista. Me gustaría una nueva instancia de myList devuelta.Personalizar Python Slicing, avise

Por favor, ayúdame a descubrir lo que está mal.

Gracias!

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] 

Respuesta

17

Ver this note:

object.__getslice__(self, i, j)

desuso desde versión 2.0: Apoyo objetos de división como parámetros al método __getitem__(). (Sin embargo, los tipos incorporados en CPython Actualmente todavía aplicar __getslice__(). Por lo tanto, hay que anularlo en clases derivadas en la aplicación de corte.

Así, puesto que subclase list tiene que sobrescribir . __getslice__, a pesar de que está en desuso

Creo que se debe evitar generalmente órdenes internas de subclases, hay demasiados detalles extraños Si lo que desea es una clase que se comporta como una lista, hay una ABC para ayudar con lo siguiente:.

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)