【问题标题】:Get "super(): no arguments" error in one case but not a similar case在一种情况下出现“super(): no arguments”错误,但在类似情况下没有
【发布时间】:2017-01-11 18:13:48
【问题描述】:
class Works(type):
    def __new__(cls, *args, **kwargs):
        print([cls,args]) # outputs [<class '__main__.Works'>, ()]
        return super().__new__(cls, args)

class DoesNotWork(type):
    def __new__(*args, **kwargs):
        print([args[0],args[:0]]) # outputs [<class '__main__.doesNotWork'>, ()]
        return super().__new__(args[0], args[:0])

Works() # is fine
DoesNotWork() # gets "RuntimeError: super(): no arguments"

据我所知,在这两种情况下 super._new__ 都将类文字作为第一个参数,并将一个空元组作为第二个参数。

那么为什么一个给出错误而另一个没有呢?

【问题讨论】:

  • 你没有在你的__new__ 中使用cls DoesNotWork...(另外——你真的应该在super() 中使用*args 以保持签名正确。 ..
  • 我没有在DoesNotWork 中明确地给__new__ 一个具体的第一个参数,但是传递的参数super() 是相同的,所以我不明白这个错误。使用 *args 会给我TypeError: type() takes 1 or 3 arguments 错误,尽管那是一个单独的问题。
  • 你使用__new__而不是__init__有什么特别的原因 - 看起来你真的想使用后者......
  • 没有理由,我只是想知道为什么我在一种情况下得到错误而不是另一种情况。
  • 在其他形式中(在非类方法中),super(cls)super(cls, the_first_argument_passed_to_this_function) 相同。我怀疑这里发生了类似的事情 - super() 试图默认为 super(first_argument_passed_to_this_function),但 *args**kwargs 不算作参数(因为它们是特殊情况),所以它失败了。

标签: python super


【解决方案1】:

super 的零参数形式要求包含它的方法具有显式(即非可变参数)第一个参数。这是an older version of the docs 建议的(强调添加):

零参数形式自动在堆栈帧中搜索类 (__class__)和第一个参数

由于某种原因,此注释已在文档的后续版本中删除。 (可能值得提出一个文档错误,因为文档对于零参数 super 的工作原理以及它工作所需的条件非常模糊。)

另请参阅this Python bug report(尚未解决,甚至没有被明确接受为错误)。结果是零参数super 是魔法,在某些情况下魔法失败了。正如错误报告中所建议的,如果您只想接受可变参数,则需要使用 super 的显式双参数形式。

【讨论】:

  • 感谢您提供答案,Python 有时如此未完成。
  • 就我而言,我的类初始化函数的第一个参数为self,而super() 正在工作。然后我在调用super() 之前添加了3-10 行代码,不知何故破坏了super()。 FWIW:我的 python 类通过skulpt在浏览器中运行...所以我的应用程序不是传统的。
  • @TrevorBoydSmith:如果你需要这方面的帮助,你应该问一个单独的问题。
  • @BrenBarn 不,我解决了这个问题。我报告说我遇到了同样的问题……但方式不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-28
  • 2017-08-09
  • 1970-01-01
  • 1970-01-01
  • 2014-04-12
  • 1970-01-01
  • 2012-11-14
相关资源
最近更新 更多