我有这段代码:
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)),)
为什么这样?我期待最后一个例子给我一个包含三个切片元素的元组。
答案 0 :(得分:1)
__getitem__
的函数签名是:
def __getitem__(self, key):
# ... etc.
每当您对对象执行项目访问权限时, 单个 参数key
都会传递给__getitem__
(与通常的实现{{1}一起}})。即使你写这样的东西也是如此:
self
上述操作会将单个元组obj[a,b,c]
作为(a, b, c)
参数传递给key
- 它会 不 导致三个参数__getitem__()
,a
和b
被传递。
由于单个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)
表单,您将收到第二个示例所期望的三个切片对象的元组。