Menu
Coddy logo textTech

メソッド解決順序

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 A

Pythonは最初に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など)を検索します。最初に見つかったメソッドが使用されます。

challenge icon

チャレンジ

中級

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

以下のファイルを編集する必要があります:

  • 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 list

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

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

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