詳細ではなく、アイデアの趣味のためにテキストをもっと読まなければならない場合があります。これはそのようなケースの1つです。
リンク先のページでは、例2.5、2.6、および2.7はすべて1つの方法を使用する必要がありますdo_your_stuff
。(つまり、do_something
に変更する必要がありますdo_your_stuff
。)
さらに、Ned Deilyが指摘したA.do_your_stuff
ように、クラスメソッドである必要があります。
class A(object):
@classmethod
def do_your_stuff(cls):
print 'This is A'
class B(A):
@classmethod
def do_your_stuff(cls):
super(B, cls).do_your_stuff()
B.do_your_stuff()
super(B, cls).do_your_stuff
バインドされたメソッドを
返します(脚注2を参照)。cls
に2番目の引数として渡されたため super()
、cls
返されたメソッドにバインドされます。つまり、クラスAcls
のメソッドの最初の引数として渡されます。do_your_stuff()
繰り返しますsuper(B, cls).do_your_stuff()
が、最初の引数としてpassedを使用してA
のdo_your_stuff
メソッドが呼び出されます。cls
それが機能するためには、A
's
do_your_stuff
はクラスメソッドでなければなりません。リンク先のページにはそのことは記載されていませんが、間違いなくそうです。
PS。do_something = classmethod(do_something)
クラスメソッドを作成する古い方法です。新しい(er)方法は、@classmethodデコレータを使用することです。
super(B, cls)
に置き換えることはできませんのでご注意くださいsuper(cls, cls)
。これを行うと、無限ループが発生する可能性があります。例えば、
class A(object):
@classmethod
def do_your_stuff(cls):
print('This is A')
class B(A):
@classmethod
def do_your_stuff(cls):
print('This is B')
# super(B, cls).do_your_stuff() # CORRECT
super(cls, cls).do_your_stuff() # WRONG
class C(B):
@classmethod
def do_your_stuff(cls):
print('This is C')
# super(C, cls).do_your_stuff() # CORRECT
super(cls, cls).do_your_stuff() # WRONG
C.do_your_stuff()
発生しますRuntimeError: maximum recursion depth exceeded while calling a Python object
。
の場合、 。の後に続くクラスをcls
検索します。C
super(cls, cls)
C.mro()
C
In [161]: C.mro()
Out[161]: [__main__.C, __main__.B, __main__.A, object]
そのクラスはであるため、がB
の場合、常に。を呼び出します。は内部で呼び出されるため、無限ループで呼び出すことになります。cls
C
super(cls, cls).do_your_stuff()
B.do_your_stuff
super(cls, cls).do_your_stuff()
B.do_your_stuff
B.do_your_stuff
Python3では、の0引数形式super
が追加されたため、super(B, cls)
で置き換えることができますsuper()
。Python3は、コンテキストからsuper()
、の定義では。class B
と同等である必要があることを認識しsuper(B, cls)
ます。
しかし、いかなる状況においてもsuper(cls, cls)
(または同様の理由でsuper(type(self), self)
)正しいことはありません。