【发布时间】:2017-12-04 05:55:15
【问题描述】:
请看以下代码:
#! /usr/bin/env python3
class MyTupleT(tuple):
def __init__(self, contents):
tuple.__init__(contents)
self.len = len(contents)
class MyTupleS(tuple):
def __init__(self, contents):
super().__init__(contents)
self.len = len(contents)
t = MyTupleT([0, 1, 2])
print(t.len, t)
s = MyTupleS([0, 1, 2])
print(s.len, s)
输出是:
3 (0, 1, 2)
Traceback (most recent call last):
File "tuple_init.py", line 16, in <module>
s = MyTupleS([0, 1, 2])
File "tuple_init.py", line 10, in __init__
super().__init__(contents)
TypeError: object.__init__() takes no parameters
The docs say 那super() 将:
返回一个代理对象,该对象将方法调用委托给类型的父类或兄弟类
这里的 IIUC super() 与 super(MyTupleS, self) 相同。现在文档进一步说
搜索顺序与
getattr()使用的相同,只是跳过了类型本身。该类型的__mro__属性列出了getattr()和super()使用的方法解析搜索顺序。
好吧,但是:
$ MyTupleS.__mro__
(__main__.MyTupleS, tuple, object)
所以super() 行应该首先在tuple 中查找__init__ 和元组的__init__ 当然可以采用一个参数(当然self 除外)并且是由显式@ 调用的987654339@ 线。那么为什么super().__init__ 调用的工作方式与此不同呢?为什么它试图调用object.__init__ 却失败了?
IIUC 只有在担心继承层次结构会在“动态执行环境”(文档中的短语)中发生变化并希望调用特定超类的方法时才需要显式指定超类。但是这个错误实际上使得必须指定超类。为什么?
注意:这与 another similarly titled question 不同。
【问题讨论】:
-
不确定这个问题有什么问题要投反对票?
-
stackoverflow.com/questions/10165405/#comment13041331_10165405 说
super()和__init__不能很好地结合在一起,这令人惊讶,因为 IIUC 经常想从__init__调用super()! -
第一个版本只有 似乎 可以工作,因为您调用了
tuple.__init__()而没有传递self(实际上,您已经传递了列表[0, 1, 2]为self)。 -
哦,是的,当实例方法被类名调用时,我们应该手动传递
self。谢谢提醒! -
对收到合法答案的合法问题投反对票会阻止像我这样的非专家因为害怕投反对票而在 SO 上提问! ????
标签: python