请参阅以下代码:
#! /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
super()
将
这里的{IUC}返回一个代理对象,该方法将方法调用委托给类型为
的父类或兄弟类
super()
与super(MyTupleS, self)
相同。现在,文档进一步说明了
搜索顺序与
getattr()
使用的搜索顺序相同,只是跳过了类型本身。该类型的__mro__
属性列出了getattr()
和super()
使用的方法解析搜索顺序。
哦,但随后:
$ MyTupleS.__mro__
(__main__.MyTupleS, tuple, object)
因此,super()
行应首先在tuple
内查找__init__
,而元组__init__
肯定可以使用一个参数({{1}除外)当然)并且是显式self
行调用的内容。那么为什么tuple.__init__
通话工作与此相同呢?为什么要尝试调用super().__init__
并失败?
IIUC只需要在担心继承层次结构可以在动态执行环境中发生变化时,只需要明确指定超类。 (来自文档的短语)并希望调用特定超类的方法。但是这个错误实际上使得必须指定超类。为什么呢?
答案 0 :(得分:2)
如果您致电tuple.__init__
,则会返回object.__init__
,因为tuple
没有自定义__init__
方法,只会从object
继承。 object.__init__
的第一个参数是self
,object.__init__
的作用是什么。因此,当您传入contents
时,它被解释为self
并且不会抛出异常。但是它可能不会按照您的想法执行,因为tuple.__new__
负责设置新的元组实例。
如果您使用super().__init__
它也会解析为object.__init__
,但它已将当前的“self”绑定为第一个参数。因此,当您将contents
传递给此函数时,它被解释为object.__init__
不存在的附加参数,因此会抛出该错误。