Python - 基本切片 vs 扩展切片

9
当我尝试使用Python 2.7进行切片实验时,发现了一种奇怪的行为:
class A:
    def __getitem__(self, i):
        print repr(i)
a=A()
a[:] #Prints slice(0, 9223372036854775807, None)
a[::] #prints slice(None, None, None)
a[:,:] #prints (slice(None, None, None), slice(None, None, None))

当在括号中使用单个冒号时,切片对象的起始为0,结束为一个巨大的整数。然而,当我使用多个冒号时,如果未指定,则起始和结束都为None。
这种行为是保证还是实现特定的? 文档 表示第二个和第三个情况是扩展切片,而第一个情况不是。然而,我找不到任何关于基本切片和扩展切片之间差异的清晰解释。
当我重写 __getitem__ 并想要接受扩展切片时,是否还有其他“特殊情况”需要注意?

使用Python 2.7,我得到的结果是2147483647(2^31-1),因此该值明显与系统相关。而在Python 3中,无论什么情况下,我都得到的是None - tobias_k
3
如果你将类 A 改为新式类,它也会变成 None - Aran-Fey
1个回答

10

对于 Python 2,[:] 仍会调用已被弃用的 __getslice__(self, i, j) 方法,且文档规定默认情况下它返回一个范围为 slice(0, sys.maxsize, None) 的切片:

请注意,在切片表达式中缺少 ij 时,它们会被分别替换为sys.maxsize,...

(这里是我自己加的强调) 新风格类默认情况下不实现 __getslice__(),所以:

如果没有找到 __getslice__(),将创建一个切片对象,并传递给 __getitem__()

Python 3 不再支持 __getslice__(),而是对上述所有切片表达式构造了一个 slice() 对象。而且 slice() 的默认参数是 None

注意:切片仅使用以下三种方法进行。例如:

a[1:2] = b

会被转换为

a[slice(1, 2, None)] = b

等等。缺少切片项始终被填充为 None


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接