継承について書かれた記事にコメントしたのですが、記事を削除されてしまったようなので、新たな記事として投稿します。
車クラスを継承してスポーツカー、エコカー、自動運転車などのクラスを作った後、運転モードを指定することで選ばれたスーパークラスのメソッドを取得して自分のメソッドとして動的メソッドオーバーライドする多重継承クラスを定義しました。
しかし、実行結果が妙なのです。
class Car(object):
def __init__(self, name):
self.name = name
def display(self, text):
print(self.name + ': ' + text);
def run(self):
self.display('run')
class SportsCar(Car):
def run(self):
self.display('run fast')
class EcoCar(Car):
def run(self):
self.display('run ecofriendly')
class AutomaticDrivingCar(Car):
def run(self):
self.display('run automatic')
class AutomaticDrivingSportyEcoCar(AutomaticDrivingCar, SportsCar, EcoCar):
def set_mode_automatic(self):
self.run = super().run
def set_mode_sports(self):
self.run = super(SportsCar, self).run
def set_mode_eco(self):
self.run = super(EcoCar, self).run
def set_mode_normal(self):
self.run = super(AutomaticDrivingCar, self).run
car1 = Car("Cedan")
car1.run()
car2 = SportsCar("GT-R")
car2.run()
car3 = AutomaticDrivingSportyEcoCar("Google")
car3.run()
car3.set_mode_sports()
car3.run()
car3.set_mode_eco()
car3.run()
car3.set_mode_normal()
car3.run()
car3.set_mode_automatic()
car3.run()
Cedan: run
GT-R: run fast
Google: run automatic
Google: run ecofriendly
Google: run
Google: run fast
Google: run automatic
処理の最後に Google の自動運転スポーティエコカーの運転モードを
自動運転⇒スポーツモード⇒エコモード⇒通常モード⇒自動運転モード
の順に切り替えたつもりだったのですが、実行結果をみると、
自動運転⇒エコモード⇒通常モード⇒スポーツモード⇒自動運転モード
の順で表示されてしまいました。
インターネットで探してみたところ、superの引数にクラス名を指定した場合、スキップするクラスを指定したことになり、多重継承順序で次のクラスが取得されるようです。
なので、狙ったクラスの一つ前のクラスを指定するといいようです。
class AutomaticDrivingSportyEcoCar(AutomaticDrivingCar, SportsCar, EcoCar):
def set_mode_automatic(self):
self.run = super().run
def set_mode_sports(self):
self.run = super(AutomaticDrivingCar, self).run
def set_mode_eco(self):
self.run = super(SportsCar, self).run
def set_mode_normal(self):
self.run = super(EcoCar, self).run
car3 = AutomaticDrivingSportyEcoCar("Google")
car3.run()
car3.set_mode_sports()
car3.run()
car3.set_mode_eco()
car3.run()
car3.set_mode_normal()
car3.run()
car3.set_mode_automatic()
car3.run()
Google: run automatic
Google: run fast
Google: run ecofriendly
Google: run
Google: run automatic
参考:
https://docs.python.jp/3/library/functions.html#super
super([type[, object-or-type]])
探索の順序は、 type 自身が飛ばされるのをのぞいて getattr() で使われるのと同じです。
原文 https://docs.python.org/3.6/library/functions.html#super
The search order is same as that used by getattr() except that the type itself is skipped.