昨年夏の横浜勉強会以来とーんとご無沙汰してたわんくま勉強会、おさしみぶりに顔出しました。日本マイクロソフト@品川新社屋に潜入したかったし。
…えー、中さんゴメンナサイ。Kinect Game DVDを一枚おシャカにしてまいました。この埋め合わせは必ずや。どうかご寛恕いただきますよう平身低頭 _o/L
今回はえムナウ御大プロデュースでWPF/Silverlightスペシャル。native屋の僕が付け入るスキなどあろうはずもなく、LTで茶を濁すことに。
LTやらせろと手ぇ挙げてはみたものの、肝心のネタを決めかね、あろうことか触り始めてわずか二時間のPythonでくっちゃべったわけですが案の定しゃべり足りんうちにTime Overコいてまいました。ちーと悔しいのでここでふぉろー。
Pythonは多重継承を許します:
class Base1:
def fun(self):
print('Base1.fun()')
class Base2:
def fun(self):
print('Base2.fun()')
class Derived(Base1,Base2):
pass # なにもしない
とか書けばDerivedはBase1とBase2から導出されます。ここで:
d = Derived() # インスタンスをこしらえて
d.fun() # fun()を呼ぶ
とかやるとd.fun()はBase1.fun()とBase2.fun()のどっちが呼ばれるでしょか。
C++でこんなの書いたらどっちのfun()を呼ぶか決めかねてコンパイルエラーです。
かたやPythonでは動いてしまいます。
d.fun()されたとき、Derivedそれ自身はfun()を持たないので、基底クラスに遡って探しにいきます。メソッドを解決する順序:MRO(Method Resolution Order)はクラス定義時にカッコ内にに並べた順となります。
class Derived(Base1,Base2):
と定義したのでMROは:
Derived
Base1
Base2
の順となり、d.fun()はBase1.fun()が呼ばれることになるです。
MROの裏をかいてみましょうか。
class Base1:
class Base2:
class Derived1(Base1,Base2): # [1]
class Derived2(Base2,Base1): # [2]
class MoreDerived(Derived1,Derived2):
こんなコード書くとMoreDerivedのMROを決定する際に([1]と[2]においてBase1とBase2の順序が異なるために)Base1とBase2のどっちを先にするか決めかねてエラーになるですよ。
よーするにPythonの多重継承は単一継承に置き換えることで実現する"なんちゃって多重継承"と考えられます。だとすれば単一継承しか許さない.NETで実装したPython処理系:IronPythonが作れるのも頷けますです。