2012-06-09 6 views
7

Czy możliwe jest przeciążenie [] (__getitem__) metod operatora i łańcucha Pythona przy użyciu początkowego odwołania do pamięci.Przeciążenie [] Operator python i metody łączenia za pomocą odwołania do pamięci

Wyobraź Mam klasy Math który akceptuje listę liczb całkowitych, tak:

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 

I chcę zrobić coś takiego:

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

Po wykonaniu tego kodu instance.list powinny być [1,2,4,5,5], czy to możliwe?

Wiem, że mógłbym zrobić coś takiego jak add_one(2,4), ale nie jest to styl API, który chciałbym mieć, jeśli to możliwe.

Dzięki

Odpowiedz

9

Jak wspomina Winston, trzeba zaimplementować pomocniczego obiektu:

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 

Jak udostępnić obiekt matematyczny z obiektem MathSlice zależy co chcesz semantyka być w przypadku zmiany obiektu Math.

+0

'xrange (* self.slice.indices (len (self.math.list)))' czuje się okropnie unpythonic. Czy istnieje lepszy sposób? – Eric

+0

Również mieszacie 'self.fields' i' self.list' – Eric

+0

@Eric: usunąłem niepotrzebny Math.add_one, i tak, że xrange (* ...) wydaje się okropnie kłopotliwe, ale nie wiem krótszy sposób. –

5

Numpy robi coś takiego.

Metoda __getitem__ otrzyma obiekt slice. Szczegóły: http://docs.python.org/reference/datamodel.html. Musisz zwrócić nowy obiekt, ale zaimplementuj ten obiekt w taki sposób, aby modyfikował oryginalną listę.

+0

Dziękuję Winston za odpowiedź. Przyjmuję odpowiedź Neda, ponieważ podaje on więcej szczegółów dotyczących implementacji i myślę, że inni użytkownicy uznają to za bardziej pomocne. Ale doceniam twoją odpowiedź. – maraujop

Powiązane problemy