super() 和@staticmethod 交互

新手上路,请多包涵

super() 不是要与静态方法一起使用吗?

当我尝试类似的东西时

class First(object):
  @staticmethod
  def getlist():
    return ['first']

class Second(First):
  @staticmethod
  def getlist():
    l = super(Second).getlist()
    l.append('second')
    return l

a = Second.getlist()
print a

我收到以下错误

Traceback (most recent call last):
  File "asdf.py", line 13, in <module>
    a = Second.getlist()
  File "asdf.py", line 9, in getlist
    l = super(Second).getlist()
AttributeError: 'super' object has no attribute 'getlist'

如果我将静态方法更改为类方法并将类实例传递给 super(),一切正常。我在这里错误地调用了 super(type) 还是我遗漏了什么?

原文由 Ben J 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 528
2 个回答

简短的回答

我在这里错误地调用了 super(type) 还是我遗漏了什么?

是:是的,你叫错了……而且(事实上, _因为_)你遗漏了一些东西。

但是不要难过;这是一个极其困难的课题。

文档 指出

如果省略第二个参数,则返回的超对象是未绑定的。

未绑定 的用例 super 对象极其狭窄且罕见。请参阅 Michele Simionato 的这些文章,了解他对 super() 的讨论:

此外,他强烈主张 在此处 从 Python 3 中删除未绑定的 super

我说过你称它为“错误”(尽管没有上下文,正确性在很大程度上是没有意义的,而且玩具示例并没有提供太多上下文)。因为 unbound super 非常罕见,而且可能完全没有道理,正如 Simionato 所说,使用 super() 的“正确”方法是提供第二个论点。

在您的情况下,使您的示例工作的最简单方法是

class First(object):
  @staticmethod
  def getlist():
    return ['first']

class Second(First):
  @staticmethod
  def getlist():
    l = super(Second, Second).getlist()  # note the 2nd argument
    l.append('second')
    return l

a = Second.getlist()
print a

如果您认为那样看起来很有趣,那您就没错。但我认为大多数人在看到 super(X) 时所期待的(或者当他们在自己的代码中尝试时希望看到的)是 Python 给你的,如果你这样做的话 super(X, X)

原文由 John Y 发布,翻译遵循 CC BY-SA 3.0 许可协议

当您在对象实例上调用普通方法时,该方法接收对象实例作为第一个参数。它可以获得对象的类及其父类,因此调用 super 是有意义的。

当您在对象实例或类上调用类方法时,该方法接收该类作为第一个参数。它可以获得父类,因此调用 super 是有意义的。

但是当你调用静态方法时,该方法不会接收任何东西,也无法知道它是从哪个对象或类调用的。这就是为什么您无法在静态方法中访问 super 的原因。

原文由 Serge Ballesta 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题