0

I'm trying to subclass the list builtin, but my new list is acting strangely and i believe __setslice__ & __getslice__ are to blame. The changes i make to the list aren't invasive and are really behind-the-scenes; so to the user, it should behave exactly like a regular list.

The problem comes when the user wants to clear a list. I executed the following test (at repl.it) and got a strange result:

class IHateCoding(list):
    def __getslice__(self, *args):
        print 'get', args
        return super(IHateCoding, self).__getslice__(*args)
        
    def __setslice__(self, *args):
        print 'set', args
        super(IHateCoding, self).__setslice__(*args)

>>> l = IHateCoding()
>>> l.extend(xrange(5))
>>> l[:] = []
set (0, 2147483647, [])

Where does this 2147483647 value come from, and why does it return a view?

EDIT:

There's one more strange output i've discovered. Can anyone explain this?

>>> l[:-1]
get (0, 2) #Expected `-1`
Community
  • 1
  • 1
Noob Saibot
  • 4,573
  • 10
  • 36
  • 60
  • P.S.: I'm not sure what the python term is for the `list[:]` operation. In numpy, it's called a view, so that's what i called it in the question. Feel free to edit if you know. – Noob Saibot Jun 07 '14 at 19:28
  • 1
    it's called a slice, hence the name of the magic method :) – Eevee Jun 07 '14 at 19:42
  • @NoobSaibot: You may want to use `__getitem__`/`__setitem__` instead of `__getslice__`/`__setslice__`. The former will give you a `slice` object which behaves in a much more sane way. `__getslice__`/`__setslice__` are deprecated since Python **2.0**, which is a *long* time ago. – nneonneo Jun 10 '14 at 17:30

1 Answers1

3

That is the value of sys.maxint, the "largest possible integer":

>>> sys.maxint
2147483647

Since you sliced without specifying a start and end, the start is zero and the end is "infinity", or the biggest integer Python can use. This is documented here.

The term for someList[:] is slicing, just like for someList[2:4], etc. It's just a slice without a start or end specified. I'm not sure quite what you mean by a "view". A slice of any length from a list returns a copy of that portion of the list. If you slice without a start or end, you get a copy of the entire list, but it's still just a slicing operation.

Note, though, that someList[:] as an expression is different from someList[:] as the target of an assignment, which is what you're doing. So doing someList[:] by itself returns a copy, but assigning to a slice with someList[:] = blah modifies the list in-place. Again, though someList[:] = blah is slice assignment, just the same as someList[2:5] is slice assignment. Assigning to a slice of a list changes the contents of that slice; if the slice is the whole list, then it replaces the entire list.

Note also that each type gets to define slicing operations differently, so the way slicing and slice assignment works on Numpy arrays is not the same as how it works on lists. Lists have no real equivalent of a numpy "view", which is essentially a reference to some part of the original array, such that modifications to the view will also modify the original array.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • @NoobSaibot: I added a bit to my answer. You seem to be thinking that `list[:]` is different from `list[2:5]`, but it's not. What you're calling a "view" is just a slice that goes all the way from the beginning to the end. – BrenBarn Jun 07 '14 at 19:33
  • I guess it's my understanding of [clearing](http://stackoverflow.com/q/850795/1658908) a list. From what i've understood from @Koba's answer, the `list[:]` operation somehow returns the "actual real list object" that all other references see. Sort of analogous to address-pointer relationship? If that's true, why does this happen--or am i off? – Noob Saibot Jun 07 '14 at 19:37
  • @NoobSaibot: I edited my answer some more. There's a difference between `someList[:]` and `someList[:] = blah`. In other words, what you're asking about is not "the `list[:]` operation" but "the `list[:] = something` operation", which is a different thing. – BrenBarn Jun 07 '14 at 19:40
  • Thanks, @BrenBarn. I've updated my question to include one more strange slicing occurrence. Instead of making a whole new duplicate question, i was wondering if you could make some sense out of this one last time? – Noob Saibot Jun 07 '14 at 20:13
  • 1
    @NoobSaibot: That is documented at the same documentation page I linked to in my answer: "If negative indexes are used in the slice, the length of the sequence is added to that index." – BrenBarn Jun 07 '14 at 20:32
  • That was my mistake. Didn't look like a link on this screen. Thanks for your help! – Noob Saibot Jun 08 '14 at 00:05
  • The docs say it is `sys.maxsize`. This difference is important on x64 Python for Windows. – Kevin Smyth Jun 15 '16 at 19:40