【问题标题】:Why can't you omit the arguments to super if you add *args in __init__ definition?如果在 __init__ 定义中添加 *args,为什么不能省略 super 的参数?
【发布时间】:2020-06-10 21:30:40
【问题描述】:
class MyClass:
    def __init__(*args):
        print(super())

MyClass()

为什么这段代码会引发RuntimeError: super(): no arguments?这是在 Python 3.7.4 中。

【问题讨论】:

  • 该方法必须有第一个参数,"new super" 才能正常工作,尽管它不必命名为 self
  • because they say so”有足够的理由吗? (即,第一个参数必须是一个简单的变量。)
  • print(super(MyClass, args[0]).__init__()) 按预期工作,无需显式命名self

标签: python python-3.x class


【解决方案1】:

根据PEP 3135,介绍了“新的super”(强调我的):

新语法:

super()

相当于:

super(__class__, <firstarg>)

其中__class__ 是定义该方法的类,并且 &lt;firstarg&gt;是方法的第一个参数(一般self表示 实例方法,cls 用于类方法)。

必须有一个特定的第一个参数才能使其工作(尽管它不一定必须被称为 selfcls),它赢了不要使用例如args[0].


至于为什么它需要是一个特定的参数,那是由于the implementation;根据评论,它使用“堆栈上的第一个局部变量”。如果co-&gt;co_argcount == 0,就像您只指定*args 一样,您会收到no arguments 错误。此行为在 CPython 以外的其他实现中可能不同。


相关

【讨论】:

  • def my_function(self) 中的selfdef my_function(*args) 中的args[0] 有什么区别?在后一种情况下,args[0] 不是函数的&lt;firstarg&gt; 吗?从 PEP 3135 中如何清楚地看出 super() 不能与 args[0] 一起使用?
  • @python481516 实际参数值之间没有区别,selfargs[0] 在这两种情况下引用同一个对象,这就是 super(MyClass, args[0]) 可以正常工作的原因。如果没有单独的显式参数,您将无法获得“自动”零参数 super 用法。
  • 谢谢,是否在 PEP 或其他 Python 文档中的任何地方都说明了 super() 工作 __init__ 必须有 explicit 第一个参数,或者它只是开发人员知道的东西根据经验?
  • @python481516 据我所知,它没有比上面更明确地记录,但是文档中的每个示例(以及我曾经写过的)都有明确的self/@ 987654355@ 这样就避免了这个问题。我将补充一点为什么实现需要这样做。
【解决方案2】:

因为__init__ 的第一个参数应该引用一个类实例。如果你传递第一个 *args 而不是一些位置参数,第一个参数变成一个元组:

class MyClass:
    def __init__(self, *args):
        print(self)
        print(args)
        print(super())

MyClass(1,2)

此代码将显示如下结果:

<__main__.MyClass object at 0x7f84228ce3c8>  
(1, 2)  
<super: <class 'MyClass'>, <MyClass object>>

&lt;__main__.MyClass object at 0x7f84228ce3c8&gt; 是对类实例的引用。你不能通过传递第一个 *args(tuple) 或 **kwargs(dict of named args) 来欺骗解释器,因为第一个参数可以只是位置参数

【讨论】:

  • def my_function(a, b, c, d, e, ...)def my_function(*args)不一样吗?函数的第一个参数的定义是什么?后一种情况,是args[0]还是args
  • @python481516 ,函数如何从外部获取参数并不重要。重要的是函数如何接收它的内部。所有未明确指定为函数参数的位置参数都将包含在元组 args 中,包括第一个。但是 python 期望第一个参数是对当前类的实例的引用,而不是元组。如果第一个参数是元组,解释器会引发错误
猜你喜欢
  • 2021-11-26
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多