メソッド解決順序
CoddyのPythonジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 21/64。
Method Resolution Order (MRO) は、複数のクラスが同じメソッド名を持っている場合に、Python がメソッドを検索するために使用する順序です。
同じメソッドを持つ複数のクラスの例を次に示します。
class A:
def method(self):
return "Method from A"
class B:
def method(self):
return "Method from B"
class C(A, B):
pass__mro__ を使って MRO を確認します:
print(C.__mro__)出力:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)__mro__ 属性は、解決順序に含まれるすべてのクラスを保持するタプルです。最初の要素 (__mro__[0]) は常にクラス自身 (C) であり、その後に左から右へ親クラス (A、次に B)、そして最後に組み込みの object クラスが続きます。
オブジェクトを作成してメソッドを呼び出します:
c = C()
print(c.method())Output:
Method from APythonは最初にクラスAでメソッドを見つけたため(MROのインデックス1)、それを使用しました。
継承順序を変更して、違いを確認します:
class D(B, A): # 今は B が A の前に来る
pass
print(D.__mro__)
d = D()
print(d.method())出力:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
Method from BこれでPythonは、継承リストの中でBがAより前にあるため、Bのメソッドを最初に見つけます。インデックス参照を使用してMRO内の特定のクラスにアクセスできます。D.__mro__[0] はD自身、D.__mro__[1] はB、そして D.__mro__[2] はAです。
mro() メソッドを使用することもできます:
print(C.mro())mro() と __mro__ は同じクラスの順序を提供しますが、型が異なります: __mro__ はタプルを返し、mro() はリストを返します。
重要なポイント:PythonはMROの順序でメソッドを検索します。まずクラス自体(インデックス0)、次にクラス定義に記載された順番どおり、左から右へ親クラス(インデックス1、2など)を検索します。最初に見つかったメソッドが使用されます。
チャレンジ
中級このチャレンジでは、クラス階層を実装します。
編集が必要なファイルは以下の通りです:
device.py: ベースとなるDeviceクラスを実装しますscreen.py:Deviceを継承するScreenクラスを実装しますcomputer.py:Deviceを継承するComputerクラスを実装しますlaptop.py: 多重継承を行うLaptopクラスを実装しますdriver.py- 実装が正しく動作することを確認するテストケースを実装します
各ファイルには、実装をステップバイステップで案内する詳細な TODO コメントが含まれています。
自分で試してみよう
# TODO: 必要なクラスをすべてインポートする
# from device import Device
# from screen import Screen
# from computer import Computer
# from laptop import Laptop
def explain_mro(class_name):
# TODO: 指定されたクラスのMRO(Method Resolution Order)を出力する
# TODO: フォーマット: "MRO for [class name]:" (注: コロンの後にスペースなし)
# TODO: class_name.__name__ を使用してクラスの名前を取得する
# TODO: class_name.__mro__ を使用してMROタプルを取得する
# TODO: MRO内の各クラス名を別々の行に出力する
# TODO: クラスのインスタンスを作成する
# TODO: インスタンスでpower_on()を呼び出し、結果を保存する
# TODO: Print: "Power on result: [result]"
# TODO: 可読性を高めるために空行を出力する
pass
# コードをテストする
# TODO: 各クラス Device、Screen、Computer、Laptop に対して explain_mro() を呼び出す
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Pythonオンラインコンパイラ