Pythonで基本クラスのclassmethodを呼び出す


105

次のコードを検討してください。

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を呼び出す方法が見つかりません。

上記の例では、Base.do(a)印刷Baseの代わりにクラスをDerivedクラス。


回答:


121

新しいスタイルのクラス(つまりobject、Python 2 から、または常にPython 3 から派生)を使用している場合は、次のsuper()ように実行できます。

super(Derived, cls).do(a)

これはprint cls, a、派生クラスclsに設定された、派生クラスからメソッドの基本クラスのバージョン(つまり)のコードを呼び出す方法です。


8
ええと.. superクラスメソッドでも使用できるようになったのはなぜですか。
Sridhar Ratnakumar、2009

これは、ベースがオブジェクトから派生している場合にのみ機能します(superによる制限があるため)。そうでない場合はどうしますか?
ars-longa-vita-brevis 2014年

ええ、これはから派生した新しいスタイルのクラスでのみ機能しobjectます。(少なくともPython 2では、ただしPy3ではすべてのクラスは新しいスタイルのIIRCだと思います)そうでない場合Base.do(self, ...)は、スーパークラスの名前をハードコーディングする必要があると思います。
David Z

内部と同じDerived.do()ではありませんか?clsDerived
Ray

@Ray Derivedサブクラスではなく実際にインスタンスである場合は、はい。
David Z

15

久しぶりですが、答えを見つけたのではないでしょうか。メソッドを装飾してクラスメソッドにする場合、元のバインドされていないメソッドは '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')

2
注:このアプローチは、super()が機能しない古いスタイルのクラスで機能します
Alex Q

2
__func__Python 2.7および3 でも利用可能
dtheodor

-3

これは私にとってはうまくいきます:

Base.do('hi')

9
cls引数は、その後にバインドされるBase代わりにDerived
シュリダールRatnakumar

私にとってうまくいくのはこれです-これはNedの答えのように(かなり)見えます:自己は、paintEvent(QPaintEvent)def paintEvent(self、qpntEvent)を持つQGraphicsViewから派生します:print dir(self)QGraphicsView.paintEvent(self、qpntEvent)
user192127 2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.