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

时间:2018-03-02 17:03:51

标签: python class

我有两个班级

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

我对super的理解是,根据https://docs.python.org/3/library/functions.html#super,只有第一个参数的super()会将super对象无限制地留给实例,所以如果你调用{{在__init__()对象上,您需要传入一个实例,因为super也是无限制的。但是,有人抱怨__init__()super(SomethingElse).__init__(SomethingElse()不是SomethingElse,它应该是从继承自type的父级继承的。

2.7.13上的

给出了object的原始错误,即super(SomethingElse).__init__()。对于TypeError: super() takes at least 1 argument (0 given),它会抛出super(SomethingElse).__init__(SomethingElse())

1 个答案:

答案 0 :(得分:2)

使用1参数调用super会产生&#34;未绑定&#34;超级对象。那些很奇怪,没有文档,大多没用,我不知道如何使用它们,但为了这个答案的目的,我们真的只需要知道一件事。

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,而不是self实例 - 但由于奇怪的实施细节,在C中实施的方法通常不会计算{{ 1}}对于这种错误信息。)

SomethingElse()在Python 3上取得成功,因为super构造函数从通常的堆栈检查魔法中提取__class__self

从类外部手动调用super(SomethingElse).__init__()会产生RuntimeError: super(): no arguments因为super.__init__尝试执行其堆栈检查魔术并且找不到__class__self }。

super(SomethingElse).__init__(SomethingElse())失败,因为super构造函数的第一个参数应该是一个类型,而不是一个实例。