2012-06-09 13 views
7

È possibile sovraccaricare i metodi di operatore e catena Python [] (__getitem__) utilizzando il riferimento di memoria iniziale.Overload [] metodi Python per operatore e concatenamento utilizzando un riferimento di memoria

Immaginate ho una classe Math che accetta un elenco di numeri interi, in questo modo:

class Math(object): 
    def __init__(self, *args, **kwargs): 
     assert(all([isinstance(item, int) for item in list(args)])) 
     self.list = list(args) 

    def add_one(self): 
     for index in range(len(self.list)): 
      self.list[index] += 1 

e voglio fare qualcosa di simile:

instance = Math(1,2,3,4,5) 
instance[2:4].add_one() 

Dopo l'esecuzione di questo codice instance.list dovrebbe essere [1,2,4,5,5], è possibile?

So che potrei fare qualcosa come add_one(2,4), ma questo non è lo stile dell'API che vorrei avere se possibile.

Grazie

risposta

9

Come cita Winston, è necessario implementare un oggetto ausiliario:

class Math(object): 
    def __init__(self, *args, **kwargs): 
     self.list = list(args) 

    def __getitem__(self, i): 
     return MathSlice(self, i) 

class MathSlice(object): 
    def __init__(self, math, slice): 
     self.math = math 
     self.slice = slice 

    def add_one(self): 
     for i in xrange(*self.slice.indices(len(self.math.list))): 
      self.math.list[i] += 1 


instance = Math(1,2,3,4,5) 
instance[2:4].add_one() 

print instance.list 

Come si condivide l'oggetto di matematica con l'oggetto MathSlice dipende da ciò che si desidera la semantica di essere se i cambiamenti oggetto Math.

+0

'xrange (* self.slice.indices (len (self.math.list)))' sembra terribilmente unpitonico. C'è un modo migliore? – Eric

+0

Inoltre, stai mixando 'self.fields' e' self.list' – Eric

+0

@Eric: Ho rimosso Math.add_one non necessario, e sì che xrange (* ...) sembra terribilmente ingombrante, ma non lo so un modo più breve. –

5

Numpy fa qualcosa del genere.

Il metodo __getitem__ riceverà un oggetto slice. Vedi http://docs.python.org/reference/datamodel.html per i dettagli. Dovrai restituire un nuovo oggetto, ma implementare quell'oggetto in modo tale da modificare l'elenco originale.

+0

Grazie Winston per la risposta. Accetto la risposta di Ned, perché sta fornendo maggiori dettagli di implementazione e penso che gli altri utenti lo troveranno più utile. Ma apprezzo la tua risposta. – maraujop

Problemi correlati