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または基本クラス名を直接使用しますが、基本クラスでclassmethodを呼び出す方法が見つからないようです。

上記の例では、classの代わりにclassをBase.do(a)出力します。BaseDerived

4

4 に答える 4

138

新しいスタイルのクラスを使用している場合(つまりobject、Python 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)

私はよくclassmethodsを使用して、オブジェクトを構築するための代替方法を提供します。以下の例では、オブジェクトの作成方法を変更するクラスメソッドのロードに上記のスーパー関数を使用しています。

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 に答える