为什么 __getitem__ 在 Python 3.5 中调用,但在 Python 2.7 中不调用?

Why is __getitem__ called in Python 3.5 but not in Python 2.7?

我有一个 subclass 字节,它提供了 __getitem__ dunder 方法。 __getitem__ 方法在 Python 3.5 中始终被调用,但在 Python 2.7 中仅针对非切片键调用。 (相反,似乎父项的 __getitem__ 已应用于该实例。)为什么会这样,是否有解决方法?

代码

class A(object):
    def __getitem__(self, key):
        print("in A.__getitem__ with key " + str(key))
        return []

class B(bytes):
    def __getitem__(self, key):
        print("in B.__getitem__ with key " + str(key))
        return []

if __name__ == "__main__":
    import sys
    print(sys.version)

    a = A()
    b = B()

    print("[0]")
    a[0]
    b[0]

    print("[0:1]")
    a[0:1]
    b[0:1]

    print("[:1]")
    a[:1]
    b[:1]

Python 3.5 输出

总是调用 class 定义的 __getitem__

(venv) snafu$ python ./x.py
3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609]
[0]
in A.__getitem__ with key 0
in B.__getitem__ with key 0
[0:1]
in A.__getitem__ with key slice(0, 1, None)
in B.__getitem__ with key slice(0, 1, None)
[:1]
in A.__getitem__ with key slice(None, 1, None)
in B.__getitem__ with key slice(None, 1, None)

Python 2.7 输出

class-defined __getitem__ 仅针对非切片键调用。

(venv2.7) snafu$ python x.py
2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609]
[0]
in A.__getitem__ with key 0
in B.__getitem__ with key 0
[0:1]
in A.__getitem__ with key slice(0, 1, None)
[:1]
in A.__getitem__ with key slice(None, 1, None)

Python 2 有 __getslice__,它优先于 __getitem__ 进行无级切片(如果存在)。在 Python 3.

中消失了