Menu
Coddy logo textTech

メソッド解決順序

CoddyのPythonジャーニー「Object Oriented Programming」セクションの一部 — レッスン 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 A

Pythonは最初にクラス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()リストを返します。

Key Point: Python searches for methods in MRO order - the class itself first (index 0), then parent classes from left to right as listed in the class definition (indices 1, 2, etc.). The first method found gets used.

challenge icon

チャレンジ

中級

このチャレンジでは、クラス階層を実装します。

編集が必要なファイルは以下の通りです:

  • 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() を呼び出す
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Object Oriented Programmingのすべてのレッスン