我有两节课
class Something(object):
def __init__(self):
self.thing = "thing"
class SomethingElse(Something):
def __init__(self):
self.thing = "another"
如你所见,一个人继承自另一个人。当我运行super(SomethingElse)
时,不会抛出任何错误。但是,当我运行super(SomethingElse).__init__()
时,我期待一个未绑定的函数调用(未绑定到假设的SomethingElse实例),所以期待__init__()
会抱怨没有接收到其self
参数的对象,但是我得到了这个错误:
TypeError: super() takes at least 1 argument (0 given)
这条消息是什么意思?
编辑:我经常看到人们手动回答super
问题,所以请不要回答,除非你真的知道super
代表是如何在这里工作,并了解描述符以及它们如何与super
一起使用。
编辑:亚历克斯建议我更新我的帖子更多细节。我现在用两种方式得到了不同的东西我用它3.6(Anaconda)。不确定发生了什么。我没有收到亚历克斯所做的,但我得到:
class Something(object):
def __init__(self):
self.thing = "thing"
class SomethingElse(Something):
def __init__(self):
super(SomethingElse).__init__()
电话(在Anaconda的3.6上):
SomethingElse()
<no problem>
super(SomethingElse).__init__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: super(): no arguments
super(SomethingElse).__init__(SomethingElse())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: super() argument 1 must be type, not SomethingElse
我对超级的理解是,根据https://docs.python.org/3/library/functions.html#super,只有第一个参数的super()
会将super
对象无限制地留给一个实例,所以如果你在__init__()
对象上调用super
,你需要传入一个实例作为__init__()
也是无限的。然而,3.6抱怨super(SomethingElse).__init__(SomethingElse()
,SomethingElse
不是type
,它应该是从继承自object
的父母继承。
在2.7.13给出super(SomethingElse).__init__()
的原始错误,这是TypeError: super() takes at least 1 argument (0 given)
。对于super(SomethingElse).__init__(SomethingElse())
,它会抛出TypeError: super() argument 1 must be type, not SomethingElse
使用1参数调用super
会生成“未绑定”的超级对象。这些都很奇怪,没有文档,而且大部分都没用,我不会深入研究它们的用途,但就本答案而言,我们实际上只需要知道一件事。
super(SomethingElse).__init__
没有通过通常的super
代理逻辑。你得到了super
实例自己的__init__
方法,而不是任何与SomethingElse
相关的方法。
从那里开始,其余的行为如下。 Python 2上的TypeError: super() takes at least 1 argument (0 given)
是因为super.__init__
至少需要1个参数,而你传递的是0.(你可能会认为它说TypeError: super() takes at least 2 arguments (1 given)
因为它仍然得到self
- super
对象self
,而不是SomethingElse
实例 - 但由于怪异实现细节,在C中实现的方法通常不会计算self
这种错误消息。)
SomethingElse()
在Python 3上获得成功,因为super
构造函数从通常的堆栈检查魔法中拉出__class__
和self
。
从类外部手动调用super(SomethingElse).__init__()
会产生RuntimeError: super(): no arguments
,因为super.__init__
尝试执行其堆栈检查魔法并且找不到__class__
或self
。
super(SomethingElse).__init__(SomethingElse())
失败,因为super
构造函数的第一个参数应该是一个类型,而不是一个实例。