为什么子类化元组和子类化列表之间存在这种差异?

kjo*_*kjo 2 python subclass subclassing

以下玩具示例有点奇怪,但它显示问题就像我可以说的那样.

首先,没有问题的部分:

class TupleWrapper(tuple):
    def __new__(cls, ignored):
        return super(TupleWrapper, cls).__new__(cls, [1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

该类TupleWrapper采用任意方式返回类似于常量的类似元组的对象(1, 2, 3).例如:

>>> TupleWrapper('foo')
(1, 2, 3)
>>> TupleWrapper(8)
(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.

现在,考虑这个类:

class ListWrapper(list):
    def __new__(cls, ignored):
        return super(ListWrapper, cls).__new__(cls, [1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

TupleWrapper除了它的子类list而不是它之外,它是相同的tuple.因此,我期待以下

>>> ListWrapper('foo')
[1, 2, 3]
>>> ListWrapper(8)
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

事实上,我得到的是

>>> ListWrapper('foo')
['f', 'o', 'o']
>>> ListWrapper(8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
Run Code Online (Sandbox Code Playgroud)

FWIW,我正在使用Python 2.7.13.

有人能帮我理解这种行为上的差异吗?

是否有可能理解它,或者它只是"只是其中一个怪癖"才能与之共存?

Ned*_*der 5

不同之处在于元组是不可变的,因此所有工作都在完成__new__.列表是可变的,因此它们的构造发生在__init__.您没有覆盖该list.__init__方法,因此它仍然像往常一样构建列表.

PS:继承自列表或元组之类的内置插件通常是一种令人沮丧和令人失望的体验,所以不要打扰:)