時々、テキストは詳細よりもアイデアの趣味のためにもっと読まなければなりません。これはそのようなケースの1つです。
ではリンク先のページ、例2.5、2.6および2.7はすべて、一つの方法を使用する必要がありますdo_your_stuff
。(つまり、do_something
に変更する必要がありますdo_your_stuff
。)
加えて、ネッド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
返さメソッドにバインドされることを。つまり、クラスAのcls
メソッドの最初の引数として渡されます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)
classmethodを作成する古い方法です。新しい(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(cls, cls).do_your_stuff()
class C(B):
@classmethod
def do_your_stuff(cls):
print('This is C')
super(cls, cls).do_your_stuff()
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)
)正しいことはありません。