简体   繁体   中英

Tuple of tuple given on slice generation

I have this code:

class Foo(object):
     def __getitem__(self, *args):
        print len(args), type(args)
        print args

This gives args as a tuple:

>>> x[1:]
1 <type 'tuple'>
(slice(1, None, None),)

But this gives args as a tuple of tuples:

>>> x[1:,2:,3:]
1 <type 'tuple'>
((slice(1, None, None), slice(2, None, None), slice(3, None, None)),)

Why so? I was expecting the last example to give me a tuple with three slice elements.

__getitem__ 's function signature is:

def __getitem__(self, key):
    # ... etc.

Whenever you perform item access on an object, a single argument key is passed to __getitem__ (alongside the usual impled self ). This is the case even if you write something like this:

obj[a,b,c]

The above will cause the single tuple (a, b, c) to be passed as the key argument to __getitem__() – it does not cause three arguments a , b and c to be passed.

Because a single key argument is always passed to __getitem__ , the effect of argument unpacking in your malformed function signature __getitem__(self, *args) is that args will always be a tuple containing exactly one item (the key).

In the first case, since you used slice syntax, that key is a slice:

 |<- slice object ->|
(slice(1, None, None),)
|<----- 1-tuple ----->|

In the second case – x[1:,2:,3:] – your single key is a tuple of 3 slice objects, which due to your malformed function signature is then wrapped in a 1-tuple:

  |<- slice object ->|  |<- slice object ->|  |<- slice object ->|
 |<-------------------------- 3-tuple --------------------------->|
((slice(1, None, None), slice(2, None, None), slice(3, None, None)),)
|<--------------------------- 1-tuple ----------------------------->|

If you change your __getitem__ signature to the conventional __getitem__(self, key) form, you'll receive the tuple of three slice objects that you expect for your second example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM