切片生成时给出的元组的元组

Tuple of tuple given on slice generation

提问人:Ankur Agarwal 提问时间:12/10/2017 最后编辑:Zero PiraeusAnkur Agarwal 更新时间:12/11/2017 访问量:37

问:

我有这个代码:

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

这给出了一个元组:args

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

但这将 args 作为元组的元组:

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

为什么会这样?我期待最后一个示例给我一个包含三个切片元素的元组。

python-2.7 slice 参数解包

评论


答:

1赞 Zero Piraeus 12/11/2017 #1

__getitem__的功能签名为:

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

每当对对象执行项目访问时,都会传递一个参数(与通常的隐含参数一起)。即使你写这样的东西,情况也是如此:key__getitem__self

obj[a,b,c]

以上将导致单个元组作为参数传递给 – 它不会导致三个参数 ,并被传递。(a, b, c)key__getitem__()abc

因为总是将单个参数传递给 ,所以在格式错误的函数签名中参数解包的效果是,该元组将始终只包含一个项目(键)。key__getitem____getitem__(self, *args)args

在第一种情况下,由于您使用了 slice 语法,因此该键是 slice:

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

在第二种情况下 – – 您的单个键是 3 个切片对象的元组,由于您的函数签名格式错误,该元组被包装在一个 1 元组中:x[1:,2:,3:]

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

如果将签名更改为常规形式,则将收到第二个示例所需的三个切片对象的元组。__getitem____getitem__(self, key)