Super()和@staticmethod 交互

Super ()不适合与 staticmethod 一起使用吗?

当我尝试

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'

如果我将 staticmethod 更改为 classmethod,并将类实例传递给 super () ,那么就可以正常工作了。我是不是把 super (type)这个词叫错了,还是我漏掉了什么?

25930 次浏览

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

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

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

简而言之

我是不是把 super (type)这个词叫错了,还是我漏掉了什么?

是的,你叫错了... ... 而且(事实上,因为)你漏掉了一些东西。

但是不要难过,这是一门极其困难的学科。

文件指出

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

不受约束 super对象的用例非常狭窄和罕见。关于 super()的讨论,请看 Michele Simionato 的这些文章:

此外,他强烈主张从 Python3给你中删除未绑定的 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)

因为 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)