2014-11-06 112 views
24

super()不是用于staticmethods吗?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 

我得到如果我改变staticmethods到classmethods并通过类的实例,以超(以下错误

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' 

),东西很好地工作。我在这里调用超级(类型)不正确还是有东西我失踪?

回答

29

简短的回答

上午我打电话超(型)不正确这里还是有我丢失的东西?

是:是的,你打电话给它不正确...(事实上,,因为)有一些你错过了。

但是不要感觉不好;这是一个非常困难的课题。

documentation注意到

如果省略了第二个参数,超级对象返回是未结合的。

未绑定的用例super对象极其狭窄和罕见。查看super()他讨论这些文章由米歇尔Simionato:

此外,他强烈主张除去未结合super来自Python 3 here

我说你称之为“不正确”(虽然正确性在没有上下文的情况下基本没有意义,而玩具的例子并没有给出太多的上下文)。正如Simionato所主张的,由于不受约束的super是非常罕见的,并且可能仅仅是不合理的,所以使用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

在Python 3中,这是否有任何不同,其中没有任何参数的'super()'是常规方法中调用它的常用方法?调用'super()。foo()'时,我在Python3中遇到了同样的问题。 – gerrit 2016-09-22 14:24:03

+4

@gerrit:Python 3的零参数'super()'仅适用于类或实例方法。这是由于它用来确定它定义哪个类的魔力。在静态方法中(就像在常规的模块级函数中一样),仍然需要两个显式参数。 (在Python 3中,单参数形式仍然未被绑定。) – 2016-09-22 22:13:30

1

当您在对象实例上调用常规方法时,该方法将接收对象实例作为第一个参数。它可以获得hte对象的类和它的父类,因此可以调用super

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

但是,当你调用一个静态方法的方法时,该方法没有收到任何东西,无法从它被调用的对象或类中知道。这就是为什么你不能以静态方法访问super的原因。