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

时间:2017-12-09 21:47:31

标签: python python-2.7 slice argument-unpacking

我有这段代码:

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)),)

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

1 个答案:

答案 0 :(得分:1)

__getitem__的函数签名是:

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

每当您对对象执行项目访问权限时, 单个 参数key都会传递给__getitem__(与通常的实现{{1}一起}})。即使你写这样的东西也是如此:

self

上述操作会将单个元组obj[a,b,c] 作为(a, b, c)参数传递给key - 它会 导致三个参数__getitem__()ab被传递。

由于单个c参数始终传递给key,因此argument unpacking在格式错误的函数签名__getitem__中的效果是__getitem__(self, *args)始终为args一个元组只包含一个项目(密钥)。

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

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

在第二种情况下 - x[1:,2:,3:] - 您的 键是3个切片对象的元组,由于您的格式错误的函数签名然后被包含在1元组:

  |<- 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)表单,您将收到第二个示例所期望的三个切片对象的元组。