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

时间:2018-07-22 17:26:28

标签: python subclass subclassing

下面的玩具示例看起来有些奇怪,但我可以简单地显示该问题。

首先,没有问题的部分:

class TupleWrapper(tuple):
    def __new__(cls, ignored):
        return super(TupleWrapper, cls).__new__(cls, [1, 2, 3])

TupleWrapper随心所欲地返回类似于常数(1, 2, 3)的类似元组的对象。例如:

>>> TupleWrapper('foo')
(1, 2, 3)
>>> TupleWrapper(8)
(1, 2, 3)

到目前为止很好。

现在,考虑这个课程:

class ListWrapper(list):
    def __new__(cls, ignored):
        return super(ListWrapper, cls).__new__(cls, [1, 2, 3])

它与TupleWrapper相同,只是它继承了list而不是tuple的子类。因此,我期望以下

>>> ListWrapper('foo')
[1, 2, 3]
>>> ListWrapper(8)
[1, 2, 3]

事实上,我得到的是

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

FWIW,我正在使用Python 2.7.13。

有人可以帮助我了解这种行为差异吗?

是否有可能理解它,还是仅仅是“怪异之一”?

1 个答案:

答案 0 :(得分:5)

区别在于元组是不可变的,因此所有工作都在__new__中完成。列表是可变的,因此它们的构造发生在__init__中。您尚未覆盖list.__init__方法,因此它仍像往常一样构造列表。

PS:从诸如list或tuple之类的内置类继承通常是令人沮丧和令人失望的体验,因此请不要打扰:)