使用 __setitem__ 还需要在 python 中实现 __len__ 2

using __setitem__ requires to also implement __len__ in python 2

这个非常简单的片段在 python 2 上失败,但在 python 3 上通过:

class A:
    def __init__(self, value):
        self.value = value

    def __setitem__(self, key, value):
        pass

r = A(1)
r[80:-10] = list(range(10))

在 python2 上,解释器调用不存在的 __len__,因此失败:

Traceback (most recent call last):
  File "prog.py", line 9, in <module>
AttributeError: A instance has no attribute '__len__'

这种行为记录在哪里?强制容器具有大小没有意义。

原因是您使用的是旧式 class。在 python 2 中,新式 class 的语法(这是 python 3 中唯一的 class 类型)是

class T(object):
    ...

这是一个老式的 class 怪癖。旧式 classes 有很多记录不详的怪癖,主要是没有跟上 Python.

变化的旧行为

这里是types.InstanceTypehas a __setslice__,负责查找老式的class__setitem____setslice__。由于此 __setslice__ 存在,Python 尝试通过 __setslice__,这需要先调用 len 以获取负切片索引。您的(旧式)class 没有 __len__,因此调用失败。

使用新样式class:

class A(object):
    ...