Python super()可选参数(以及super()的机制)

问题描述 投票:-1回答:1

我有两节课

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

python class
1个回答
2
投票

使用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构造函数的第一个参数应该是一个类型,而不是一个实例。

© www.soinside.com 2019 - 2024. All rights reserved.