super()和@staticmethod交互

时间:2014-11-06 19:52:35

标签: python python-2.7 static-methods super

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

我收到以下错误

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'

如果我将staticmethods更改为classmethods并将类实例传递给super(),那么一切正常。我在这里打电话给超级(打字)还是我错过了什么?

3 个答案:

答案 0 :(得分:46)

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

是:是的,你是错误地调用它...而且(实际上,因为)有一些你缺少的东西。

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

documentation注明

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

未绑定 super对象的用例非常狭窄且极为罕见。请参阅Michele Simionato关于super()的讨论的这些文章:

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

我说你称它为“错误”(虽然没有上下文,正确性在很大程度上是无意义的,玩具示例并没有给出太多背景信息)。因为未绑定的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)

答案 1 :(得分:1)

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

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

是有意义的

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

答案 2 :(得分:0)

由于Second继承了First的形式,因此您只能使用First.getlist()而不是在super(即super(Second, Second))中传入两个参数

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

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

a = Second.getlist()
print (a)