2011-08-17 8 views
5

Przeczytałem coś o plasterku w python3. Potem napisałem program, próbowałem wdrożyć getitem (self, plaster (y)). Kod spadnie poniżej:[python]: jak zaimplementować plaster w python3?

class NewList: 
    def __init__(self, lst): 
     print('new list') 
     self._list = lst 
    def __getitem__(self, x): 
     if type(x) is slice: 
      return [ self._list[n] for n in range(x.start, x.stop, x.step) ] #error? 
     else: 
      return self._list[x] 
    ... 

nl1 = NewList([1,2,3,4,5]) 
nl1[1:3] #error occurs 

potem znalazłem się x.step jest None, co czyniło range podnieść wyjątek. Jak zatem wdrożyć metodę getitem?

+0

Twoja klasa 'NewList' powinna dziedziczyć z' list' ... – JBernardo

+0

@JBernardo - Czy chcesz uniknąć jawnego używania obiektów slice? – Alcott

Odpowiedz

2

trzeba użyć metody slice.indices. Biorąc pod uwagę długość sekwencji, zwraca krotki start, stop, krok:

>>> s = slice(2, 5, None) 
>>> s.indices(10) 
(2, 5, 1) 

>>> [x for x in range(*s.indices(10))] 
[2, 3, 4] 

>>> s.indices(3) 
(2, 3, 1) 

>>> s.indices(0) 
(0, 0, 1) 
0

Co powiecie na x.step or 1?

class NewList: 
    def __init__(self, lst): 
     print('new list') 
     self._list = lst 
    def __getitem__(self, x): 
     if type(x) is slice: 
      return [ self._list[n] for n in range(x.start, x.stop, x.step or 1) ] #error? 
     else: 
      return self._list[x] 

nl1 = NewList([1,2,3,4,5]) 
nl1[1:3] 
+0

ya, to sposób na obejście problemu, ale zgodnie z tym, co czytam, nie. – Alcott

2

Jeśli x jest kawałek, można zrobić to samo jak inne stan:

return self._list[x] 
+0

absolutnie tak, ale ja chcę tylko wiedzieć, jak to zrobić samemu. – Alcott

+0

@Alcott, nie jestem pewien, co masz na myśli mówiąc "zrób to sam". –

+1

Przepraszam, chodzi mi o to, że chcę wiedzieć, w jaki sposób __getitem __ (self, slice) zaimplementowano na liście. – Alcott

4

W przypadku, gdy nie znamy długość obiektu jest oczywisty podstęp, aby obejść ten parametr obowiązkowy. Na przykład ciąg nieskończony za GetItem może wyglądać następująco:

def __getitem__(self, key) : 
    if isinstance(key, slice) : 
     m = max(key.start, key.stop) 
     return [self[ii] for ii in xrange(*key.indices(m+1))] 
    elif isinstance(key, int) : 
     #Handle int indices 

Będzie to nie tylko wtedy, gdy nie dają start i stop, ale z sprawdzanie Żaden to może być obsługiwane za.

+0

'xrange' nie istnieje w python3, zamiast tego powinniśmy użyć' range'. również za pomocą tej implementacji nie można mieć plasterków takich jak '[: 4]', ponieważ 'max' nie może obsłużyć typu' None'. Zamiast tego powinieneś sprawdzić, czy start i stop nie są "Brak", a jeśli tak, to przypisz je odpowiednio do zer i len przedmiotów. Również dobrze jest włączyć 'key.step' w' zakresie'. – sazary