多重継承時のメソッドの解決順序について

id:amachangに「PerlではMRO(Method Resolution Order, メソッドの解決順序)は幅優先探索とかC3ってのとかが外付けのライブラリで選べるような仕組みになっているけども、Pythonはどうなの?と聞かれてわからなかったので調べました。

新しいクラスでは

>>> class A(object):
	pass

>>> class B(object):
	pass

>>> class AB(A, B):
	pass

>>> class BA(B, A):
	pass

>>> class ABBA(AB, BA):
	pass


Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    class ABBA(AB, BA):
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases A, B

C3 linearization - Wikipedia, the free encyclopedia
http://en.wikipedia.org/wiki/C3_linearization
かな?

古いクラスで同じことをやってもエラーにはなりません。あんまり意識していないけどいろいろ違うんだなぁ。

        • -

そうそう、「すべての親クラスを探索し終わってから祖父クラスを探す」という理解をしている人が多い(僕も含めて)ようだけど、それは間違い。

>>> class C(object):
	def foo(self):
		return "C"

	
>>> class A(object):
	def foo(self):
		return "A"

>>> class B1(A):
	pass

>>> class B2(A):
	pass

>>> class D(B1, B2, C):
	pass

>>> D().foo()
'A'