[解決済み] 新スタイルのクラスにおけるMRO(Method Resolution Order)とは?
質問
本の中で
Python in a Nutshell (第2版)
を使用した例があります。
古いスタイルのクラスを使って、どのようにメソッドが古典的な解決順序で解決されるかを示す例と
新しい順序でどのように異なるかを示します。
同じ例を新しいスタイルに書き換えて試してみましたが、結果は古いスタイルのクラスで得られたものと変わりません。この例を実行するために使用している Python のバージョンは次のとおりです。 2.5.2. 以下はその例です。
class Base1(object):
def amethod(self): print "Base1"
class Base2(Base1):
pass
class Base3(object):
def amethod(self): print "Base3"
class Derived(Base2,Base3):
pass
instance = Derived()
instance.amethod()
print Derived.__mro__
呼び出し
instance.amethod()
が印刷されます。
Base1
と表示されますが、新しいスタイルのクラスを持つMROの私の理解では、出力は次のようになるはずです。
Base3
. 呼び出しは
Derived.__mro__
をプリントします。
(<class '__main__.Derived'>, <class '__main__.Base2'>, <class '__main__.Base1'>, <class '__main__.Base3'>, <type 'object'>)
新しいスタイルクラスを持つMROの私の理解は間違っているのか、それとも私が発見できない愚かな間違いを犯しているのか、よくわかりません。MRO をよりよく理解するために、私を助けてください。
どのように解決するのですか?
レガシー クラスと新スタイル クラスの解決順序の決定的な違いは、quot;naive" の深さ優先のアプローチで同じ祖先クラスが複数回出現する場合に生じます -- 例: ダイヤモンド継承の場合を考えてみてください。
>>> class A: x = 'a'
...
>>> class B(A): pass
...
>>> class C(A): x = 'c'
...
>>> class D(B, C): pass
...
>>> D.x
'a'
ここで、レガシースタイルでは、解決順序は D - B - A - C - A : なので、D.x を調べるとき、A は解決順序の最初の拠点となり、それによって C に定義が隠されていることになります。
>>> class A(object): x = 'a'
...
>>> class B(A): pass
...
>>> class C(A): x = 'c'
...
>>> class D(B, C): pass
...
>>> D.x
'c'
>>>
ここで、ニュースタイルでは、順番は
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>,
<class '__main__.A'>, <type 'object'>)
で
A
は一度だけ、そのサブクラスのすべての後に解決順序で来ることを強制されるので、オーバーライド (すなわち、C によるメンバー
x
の C のオーバーライド) が実際に賢明に機能するようにします。
これは、旧式のクラスが避けられるべき理由の一つです。quot;ダイヤモンドライク"パターンによる多重継承は、新式のクラスではうまくいきますが、旧式のクラスでは感覚的にうまくいかないのです。
関連
-
[解決済み] Pythonのsuper()は多重継承でどう動くのか?
-
[解決済み] Pythonの旧スタイルのクラスと新スタイルのクラスの違いは何ですか?
-
[解決済み] Pythonで子クラスから親クラスのメソッドを呼び出すにはどうすればよいですか?
-
[解決済み] Pythonのキャッシュライブラリはありますか?
-
[解決済み] DataFrameに日付間の日数カラムを追加する pandas
-
[解決済み] ファブリック経由でデプロイユーザとしてvirtualenvを有効化する
-
[解決済み] 文字列のリストを内容に基づいてフィルタリングする
-
[解決済み] Cythonのコードを含むPythonパッケージはどのように構成すればよいのでしょうか?
-
[解決済み] あるメソッドが複数の引数のうち1つの引数で呼び出されたことを保証する
-
[解決済み] Python の sorted() はどのようなアルゴリズムを使っているのですか?重複
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Pythonのsuper()は多重継承でどう動くのか?
-
[解決済み] Pythonで'super'は何をするのですか?- super().__init__() と明示的なスーパークラス __init__() の違い
-
[解決済み] 2つの線分が交差しているかどうかを確認するにはどうすればよいですか?
-
[解決済み] Jupyterノートブックでenv変数を設定する方法
-
[解決済み] Pythonのキャッシュライブラリはありますか?
-
[解決済み] バブルソートの宿題
-
[解決済み] Spyderを仮想環境で動作させるには?
-
[解決済み] PythonからSMTPを使用してメールを送信する
-
[解決済み] ファブリック経由でデプロイユーザとしてvirtualenvを有効化する
-
[解決済み] 認証プラグイン 'caching_sha2_password' はサポートされていません。