Python.use(better)《5》継承に警鐘を鳴らす(その伍)

記事一覧 Python.use(better)《Python3.1》

継承に警鐘を鳴らす(その伍)

《著》後藤いるか・伊藤うさぎ・小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第1版♪1988/05/23 ● 第2版♪2001/01/29 ● 第3版♪2009/12/15

オブジェクト指向プログラミング〔OOP〕の基本概念の理解を深めます。
※ JPython1.1/Jython2.2 で作成した例題を、Python3.1 で再構成しました。


継承に警鐘を鳴らす(その伍)

継承の概念を実現するのに、いくつかの方法があります。そのひとつが、クラスを使って実現するというものです。次に(2a)親子関係にあるクラスをどのように表現するかを紹介します。


《note》図は、簡略したタプルのモデルを含みます。詳細は、以下(および関連記事)で紹介します。□

■ 親クラスのメソッドを再定義する

新しいクラスを定義するときに、親クラスのメソッドを再定義する意義について考察します。

    class Replace(Piyo):
        def happy(self):
            print("Yes, as happy as happy can be!")

クラス Replace は、既存のクラス Piyo を親に持ち、既存のメソッド hello を再定義しています。

■ クラスオブジェクト

クラスも「呼び出し可能オブジェクト」なので、演算子 () を利用できます。

>>> p3 = Replace(); p3
<__main__.Replace object at 0x135bb30>

クラスオブジェクト Replace に演算子 () を適用すると、新たなインスタンスオブジェクトを生成します。変数 p3 は、生成した(クラス Replace の)インスタンスオブジェクトを束縛します。対話モードでは、式 p3 を評価すると、変数 p3 が束縛するオブジェクトに固有の識別情報が出力されます。すると、p3 は(Piyo ではなく)Replace のインスタンスオブジェクト __main__.Replace object で、固有の識別情報 0x135bbd0 を持つのが分かります。この識別情報は、その状況(実行環境)ごとに値が異なります。

>>> p3.happy()
Yes, as happy as happy can be!

式 p3.happy() を評価すると、インスタンスオブジェクト p3 が属するクラス Replace で再定義したメソッド happy を呼び出します。すると、メソッド happy の本体に記述したコードの断片を実行して、文字列 "Yes, as happy as happy can be!" を出力します。

演算子:in

演算子 in を利用すると、指定したキーがメソッド辞書に含まれるかが分かります。

>>> "happy" in Replace.__dict__
True
>>> "happy" in Piyo.__dict__
True

インスタンスオブジェクト p3 が属するクラス Replace のメソッド辞書には、キー要素 "happy" が含まれます。また、その親クラス Piyo のメソッド辞書にも、キー要素 "happy" が含まれます。そのため、メソッド呼び出し p3.happy() に呼応する関数オブジェクトは、(クラス Piyo ではなく)クラス Replace のメソッド辞書に帰結します。なぜなら、Piyo.__dict__["happy"] を検索する前に、Replace.__dict__["happy"] が見つかるからです。そのため、同じメソッド呼び出し happy() に対して、同じ親クラス Piyo の子孫でも、(Inherit) p2 と (Replace) p3 では異なる動作をします。

■ 特殊属性:__func__

特殊属性 __func__ を参照すると、そのメソッドオブジェクトが保持する、関数オブジェクトが得られます。

    
> >>> hex(id(p3.happy)) '0x124e620'
>>> p3.__class__.__dict__["happy"]
インスタンスオブジェクトも(他のオブジェクトと同様に)属性を介して、他のオブジェクトを参照できます。ただし、インスタンスオブジェクト p3 が、インスタンス属性 happy を持つものの、特殊属性 __func__ を介さないと、関数オブジェクトは得られません。そのため、p3.happy という表現は、p3.__class__.__dict__["happy"] の簡略表記(近道)と見なせます。
>>> p3.happy()
Yes, as happy as happy can be!
>>> p3.__class__.__dict__["happy"](p3)
Yes, as happy as happy can be!
関数オブジェクト p3.happy(束縛メソッド)は「呼び出し可能オブジェクト」なので、演算子 () を適用できます。ただし、非束縛メソッド関数は、実引数 p3 が必要になります。
■ 特殊属性:__code__
特殊属性 __code__ を参照すると、その関数定義に即した、コードオブジェクトが得られます。
    
>>> type(code)
'happy'
('self',)
1
コードオブジェクトのインスタンス属性を参照すると、関数定義を反映した、関数名'happy'、引数名'self' などの情報が得られます。 》こちらに移動中です《TOP

関連記事

Last updated♪2010/01/19