super()和@staticmethod交互

Ben*_*Ben 42 python static-methods super python-2.7

super()是不是要用于staticmethods?

当我尝试类似的东西

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
Run Code Online (Sandbox Code Playgroud)

我收到以下错误

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'
Run Code Online (Sandbox Code Playgroud)

如果我将staticmethods更改为classmethods并将类实例传递给super(),那么一切正常.我在这里不正确地调用超级(类型)还是有些东西我不见了?

Joh*_*n Y 55

答案简短

我在这里不正确地调用超级(类型)还是有些东西我不见了?

是的:是的,你正在调用它......并且(确实,因为)有一些你缺少的东西.

但不要心疼; 这是一个非常困难的主题.

文件指出,

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

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

此外,他强烈主张在这里删除未绑定super的Python 3 .

我说你称之为"错误"(虽然没有上下文,正确性在很大程度上是毫无意义的,而玩具示例并没有给出太多背景信息).因为未绑定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
Run Code Online (Sandbox Code Playgroud)

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

  • @gerrit:Python 3的零参数`super()`仅适用于类或实例方法.这是由于它用来确定它所定义的类的魔力.在静态方法中(就像常规的模块级函数一样),你仍然需要两个显式参数.(单参数形式在Python 3中仍然未绑定.) (8认同)
  • 这在Python 3中有什么不同,其中`super()`没有任何参数是通常的方法在常规方法中调用它?调用`super().foo()时,我在Python3中遇到了同样的问题. (4认同)

Ser*_*sta 7

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

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

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