メソッド解決順序
CoddyのPythonジャーニー「Object Oriented Programming」セクションの一部 — レッスン 21/64。
メソッド解決順序 (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())出力:
Method from APythonは最初にclass 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継承リストの中でBがAよりも前に記述されているため、PythonはまずBのメソッドを見つけます。インデックスを使用してMRO内の特定のクラスにアクセスできます。D.__mro__[0] はD自身、D.__mro__[1] はB、そして D.__mro__[2] はAとなります。
また、mro() メソッドを使用することもできます:
print(C.mro())これは __mro__ と同じ結果をリストとして返します。
重要なポイント: PythonはMRO(メソッド解決順序)の順に従ってメソッドを検索します。最初にクラス自身(インデックス0)、次にクラス定義に記載されている左から右の順で親クラス(インデックス1、2など)を検索します。最初に見つかったメソッドが使用されます。
チャレンジ
中級このチャレンジでは、クラス継承を実装します。
以下のファイルを編集する必要があります:
device.py: ベースとなるDeviceクラスを実装しますscreen.py:Deviceを継承するScreenクラスを実装しますcomputer.py:Deviceを継承するComputerクラスを実装しますlaptop.py: 多重継承を使用してLaptopクラスを実装しますdriver.py- 実装が正しく動作することを確認するためのテストケースを実装します
各ファイルには、実装をステップバイステップでガイドする詳細な TODO コメントが含まれています。
チートシート
メソッド解決順序 (MRO) は、複数のクラスが同じメソッド名を持つ場合に、Python がメソッドを探すために使用する順序です。
__mro__ または mro() を使用して MRO を確認します:
class A:
def method(self):
return "Method from A"
class B:
def method(self):
return "Method from B"
class C(A, B):
pass
print(C.__mro__)
print(C.mro()) # Same result as a listPython は MRO の順序でメソッドを検索します。まずクラス自体、次にクラス定義に記載されている左から右の順序で親クラスを検索します:
c = C()
print(c.method()) # "Method from A" - A comes before B
class D(B, A): # B comes before A now
pass
d = D()
print(d.method()) # "Method from B" - B comes before A自分で試してみよう
# TODO: 必要なすべてのクラスをインポートする
# from device import Device
# from screen import Screen
# from computer import Computer
# from laptop import Laptop
def explain_mro(class_name):
# TODO: 指定されたクラスのMRO(メソッド解決順序)を表示する
# TODO: フォーマット: "MRO for [class name]:" (注意: コロンの後にスペースを入れない)
# TODO: クラス名を取得するには class_name.__name__ を使用する
# TODO: MROのタプルを取得するには class_name.__mro__ を使用する
# TODO: MRO内の各クラス名を個別の行に表示する
# TODO: クラスのインスタンスを作成する
# TODO: インスタンスの power_on() を呼び出し、結果を保存する
# TODO: 表示: "Power on result: [result]"
# TODO: 読みやすさのために空行を表示する
pass
# コードをテストする
# TODO: 各クラス(Device, Screen, Computer, Laptop)で explain_mro() を呼び出す
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。