Python.use(better)《3》継承に警鐘を鳴らす(その参)
‖記事一覧‖ Python.use(better)《Python3.1》
継承に警鐘を鳴らす(その参)
《著》後藤いるか・伊藤うさぎ・小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第1版♪1988/05/23 ● 第2版♪2001/01/29 ● 第3版♪2009/12/15
オブジェクト指向プログラミング〔OOP〕の基本概念の理解を深めます。
※ JPython1.1/Jython2.2 で作成した例題を、Python3.1 で再構成しました。
継承に警鐘を鳴らす(その参)
継承の概念を実現するのに、いくつかの方法があります。そのひとつが、クラスを利用するというものです。まず、クラスをどのように表現するかを紹介します。
《note》図は、簡略した辞書のモデルを含みます。詳細は、以下(および関連記事)で紹介します。□
- 2006-02-05 Python.use(better) #OOP への扉を開く:コンテナー
■ クラスを定義する
単独でクラスを定義します。
class Piyo: def happy(self): print("Are you Happy?")
クラス Piyo には、メソッド happy を定義します。
■ クラスオブジェクト
クラスも「呼び出し可能オブジェクト」なので、演算子 () を利用できます。
>>> p1 = Piyo(); p1
<__main__.Piyo object at 0x135b910>
クラスオブジェクト Piyo に演算子 () を適用すると、新たなインスタンスオブジェクトを生成します。変数 p1 は、生成した(クラス Piyo の)インスタンスオブジェクトを束縛します。対話モードでは、式 p1 を評価すると、変数 p1 が束縛するオブジェクトに固有の識別情報が出力されます。すると、p1 は、Piyo のインスタンスオブジェクト __main__.Piyo object で、固有の識別情報 0x135b910 を持つのが分かります。この識別情報は、その状況(実行環境)ごとに値が異なります。
Are you Happy?式 p1.happy() を評価すると、インスタンスオブジェクト p1 が属するクラス Piyo で定義したメソッド happy を呼び出します。すると、メソッド happy の本体に記述したコードの断片を評価して、文字列 "Are you Happy?" を出力します。■ 特殊属性:__class__
特殊属性 __class__ を参照すると、そのインスタンスオブジェクトが属する、クラスオブジェクトが得られます。>>> hex(id(p1.__class__)) '0x4b2a40' >>> hex(id(Piyo)) '0x4b2a40'
p1 のインスタンス属性 __class__ を介して、クラスオブジェクト Piyo が得られます。つまり、クラスと同じ名前の変数 Piyo が束縛するオブジェクトと見なせます。■ 特殊属性:__dict__
特殊属性 __dict__ を参照すると、メソッド辞書オブジェクトが得られます。>>> hex(id(p1.__class__.__dict__)) '0x135b9d0' >>> hex(id(Piyo.__dict__)) '0x135b9d0'p1 のインスタンス属性 __class__ を介しても、Piyo のクラス属性 __dict__ を介して得られるのは、同じメソッド辞書オブジェクトです。>>> hex(id(p1.__class__.__dict__["happy"])) '0x125e0c0'メソッド辞書オブジェクトは、メソッドと同じ名前のキー属性を持ちます。そのため、キー属性 "happy" を参照すると(対応する値属性として)関数オブジェクト happy が得られます。■ 関数オブジェクト
関数も「オブジェクト」なので、固有の識別情報を持ちます。>>> Piyo.happyクラスオブジェクトも(他のオブジェクトと同様に)属性を介して、他のオブジェクトを参照できます。ただし、クラスオブジェクト Piyo が、クラス属性 happy を持つかのように見えて、クラス属性 __dict__ を介して、メソッド辞書からクラス属性と同じ名前の文字列(キー要素)対応する関数オブジェクト(値要素)を得ています。>>> Piyo.__dict__["happy"] ■ 特殊属性:__func__
特殊属性 __func__ を参照すると、そのメソッドオブジェクトが保持する、関数オブジェクトが得られます。>>> p1.happyインスタンスオブジェクトも(他のオブジェクトと同様に)属性を介して、他のオブジェクトを参照できます。ただし、インスタンスオブジェクト p1 が、インスタンス属性 happy を持つものの、特殊属性 __func__ を介さないと、関数オブジェクトは得られません。そのため、p1.happy という表現は、p1.__class__.__dict__["happy"] の簡略表記(近道)と見なせます。> >>> hex(id(p1.happy)) '0x124e620' >>> hex(id(p1.happy.__func__)) '0x125e0c0' ■ 束縛メソッド
メソッド呼び出しには、実行時に確定するオブジェクト(慣例では、変数 self で参照する)の存在が不可欠です。そのため「束縛メソッド」と「非束縛メソッド」とに分類されます。>>> p1 = Piyo() >>> p1.happy() #1: bound method Are you Happy? >>> Piyo.happy(p1) #2: un-bound method Are you Happy? >>> Piyo.__dict__["happy"](p1) Are you Happy?束縛メソッド happy #1 は、実行時に確定するインスタンスオブジェクト p1 の他に、実引数を指定する必要はありません。しかし、未束縛メソッド happy #2 は、1つの実引数(インスタンスオブジェクト p1)を指定する必要があります。 》こちらに移動中です《 ↑TOP