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

标签 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。

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

是否有可能理解它,或者它“只是其中之一”,人们只能忍受?

最佳答案

不同之处在于元组是不可变的,因此所有工作都在 __new__ 中完成。列表是可变的,因此它们的构造发生在 __init__ 中。您尚未重写 list.__init__ 方法,因此它仍在照常构建列表。

PS:从列表或元组等内置函数继承通常是一种令人沮丧和失望的体验,所以不要打扰:)

关于python - 为什么子类化元组和子类化列表之间存在这种差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51467582/

相关文章:

python - 从命令行运行 Plotly 脚本

c++ - 当我定义一个子类只是为了抽象出基类构造函数的细节时,它叫什么?

c# - 在 ASP.NET 中子类化 DropDownList

ios - 我应该选择哪一个,子类化或类别

python - 为什么/什么时候在 Python 中 `x==y` 调用 `y.__eq__(x)` ?

python - 不规则间隔的热图

python - 清理导入的 pandas 数据框中的 header

java - 父类访问子类Java的 protected 成员

ios - 子类化 UITableViewCell 不显示添加的样式

ios - 在 Swift 中子类化 PFObject