kenkovlog

けんこふたんっオフィシャユブヨグッ
アンッ!アンッ!アンッ!アンッ!

Python のクラスについてまとめ

Python のクラスについて復習をばっ

Python のクラスは(おおまかに言えば) 名前空間をリンクで結んだものです。 ですからクラスのリンクを辿る方法と、それに基づいて名前が解決される方法を理解することがまず重要です。

オブジェクト

Python では クラスインスタンス はともに オブジェクト です。 class ステートメントが実行されるとクラスオブジェクトが作成されてトップレベルで定義されている メソッドなどがオジェクトとして変数に代入されます。

リンク

クラスとインスタンスは リンク で結ばれています。図のように、インスタンスは __class__ により クラス名を取得できます。クラスは __name__ で自分自身のクラス名を取得でき、 __bases__ で 継承しているクラス名を取得できます。

../../../_images/class.png

インスタンスとクラスはこれによりリンクされています。上の図だとインスタンスI はクラスC1 とリンクして、 クラスC1 はクラスC2, C3 とリンクされています。

名前の解決

さて、

$ I = C1()
$ I.attribute_name

とした時の名前解決の方法を見てみましょう。この場合I から順番に名前が見つかるまでリンクをさかのぼっていきます。 さかのぼる順は 旧スタイルクラス では左からの深さ優先探索、 真スタイルクラス では左からの幅優先探索 です。

メソッドが

$ I.method()

と呼びだされた時、これは

$ C1.method(I)

として呼びだされるため、C1 から探索がはじまります。(詳しくは 結合メソッド非結合メソッド を参照)

継承によるオーバーライドは、リンクの考えからすると、検索の結果先にヒットしているだけです。

属性

クラス、インスタンスが持っている属性は __dict__ で調べることができます。ただしこれは継承によって受けつがれた属性 (リンクされている他のクラスで定義されている属性) は含まれません。本当にそのクラス、インスタンスが持っている属性を 返します。

注釈

__dict__ はドキュメントによれば 読み書き可能な 属性のみを含みます。 ですので __dict__ を見ても例えば__dict__ 自身は含まれていないことがわかります。 なぜなら__dict__ は読み込み専用の属性だからです。

継承されている属性(リンクされているクラスを辿って得られる属性) 全てを表示するには組み込み関数の dir を使います。 しかし、dir の内容は __dir__ によりカスタマイズされるため、正確な内容が返される保証はありません。 もし __dir__ が定義されていない場合は __dict__ が使われます。

けんこふたん