122

考虑以下代码:

class Base(object):

    @classmethod
    def do(cls, a):
        print cls, a

class Derived(Base):

    @classmethod
    def do(cls, a):
        print 'In derived!'
        # Base.do(cls, a) -- can't pass `cls`
        Base.do(a)

if __name__ == '__main__':
    d = Derived()
    d.do('hello')

> $ python play.py  
> In derived! 
> <class '__main__.Base'> msg

Derived.do,我怎么称呼Base.do

如果这是一个普通的对象方法,我通常会直接使用super甚至直接使用基类名称,但显然我找不到在基类中调用类方法的方法。

在上面的示例中,Base.do(a)打印Base类而不是Derived类。

4

4 回答 4

138

如果您使用的是新式类(即从objectPython 2 派生,或始终在 Python 3 中派生),您可以这样做super()

super(Derived, cls).do(a)

这就是您将如何print cls, a从派生类调用基类版本的方法(即)中的代码,并将cls其设置为派生类。

于 2009-08-12T23:09:50.650 回答
16

这已经有一段时间了,但我想我可能已经找到了答案。当你装饰一个方法成为一个类方法时,原始的未绑定方法存储在一个名为“im_func”的属性中:

class Base(object):
    @classmethod
    def do(cls, a):
        print cls, a

class Derived(Base):

    @classmethod
    def do(cls, a):
        print 'In derived!'
        # Base.do(cls, a) -- can't pass `cls`
        Base.do.im_func(cls, a)

if __name__ == '__main__':
    d = Derived()
    d.do('hello')
于 2011-04-15T21:01:49.920 回答
2

基于@David Z 的答案,使用:

super(Derived, cls).do(a)

可以进一步简化为:

super(cls, cls).do(a)

我经常使用类方法来提供替代方法来构造我的对象。在下面的示例中,我使用上面的超级函数来更改对象创建方式的类方法加载:

class Base():
    
    def __init__(self,a):
        self.a = a
    
    @classmethod
    def load(cls,a):
        return cls(a=a)
    
class SubBase(Base): 

    @classmethod
    def load(cls,b):
        a = b-1
        return super(cls,cls).load(a=a)
    
base = Base.load(a=1)
print(base)
print(base.a)

sub = SubBase.load(b=3)
print(sub)
print(sub.a)

输出:

<__main__.Base object at 0x128E48B0>
1
<__main__.SubBase object at 0x128E4710>
2
于 2020-10-13T08:09:07.427 回答
-4

这对我有用:

Base.do('hi')
于 2009-08-12T23:12:48.367 回答