C Smith wrote:
### class Ring(list): def __init__(self, l): self[:] = l self._zero = 0 def turn(self, incr=1): self._zero+=incr
def __getitem__(self, i): return self[(i-self._zero)%len(self)]
l=Ring(range(10)) print l l.turn(5) print l #same as original print l[0] #crashes python ###
This is a classic mistake. l[0] --> l.__getitem__(l, 0), which you understand. However in __getitem__ you then call self[] which will just call __getitem__ again. and again. and again. ....
The way out is to explicitly call the parent's __getitem__.
def __getitem__(self, i): # list is out parent, call its method return list.__getitem__(self, (i - self._zero) % len(self))
Two other changes:
- in __init__(), instead of modifying self, I think it is safer to call list.__init__(). This is the usual thing do do in a subclass.
- You can change the behaviour of print by defining __repr__() or __str__().
Here is a complete version that seems to work, though you may find other list methods you need to override:
class Ring(list): def __init__(self, l): list.__init__(self, l) self._zero = 0
def turn(self, incr=1): self._zero+=incr
def __getitem__(self, i): return list.__getitem__(self, (i - self._zero) % len(self))
def __repr__(self): return repr([self[i] for i in range(len(self))])
l=Ring(range(10)) print l l.turn(5) print l print l[0]
Kent
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor