Python.use(better) #OOP:識別性 -- 関数オブジェクト
‖記事一覧‖ Python.use(better)《Python3.1》
識別性 -- 関数オブジェクト
《著》真樹育未、小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第1版♪1988/05/23 ● 第2版♪2001/01/29 ● 第3版♪2009/12/15
オブジェクト指向プログラミング〔OOP〕の基本概念の理解を深めます。
※ Python1.5 で作成した例題を、Python3.1 で再構成しました。
オブジェクトの3要素
オブジェクトを特徴付ける3要素として、
- 識別性〔identity〕
- 状態〔state〕
- 振舞〔behavior〕
が挙げられます。
概要
関数やクラスを定義するということは、その名前と同じ変数によって、生成した関数オブジェクトやクラスオブジェクトを束縛しているにすぎません。
- 2006-01-20 Python.use(better) #OOP:識別性〔identity〕整数オブジェクト
- 2006-01-24 Python.use(better) #OOP:識別性〔identity〕関数オブジェクト
- 2006-01-25 Python.use(better) #OOP:識別性〔identity〕クラスオブジェクト
《承前》
関数を定義するということ
関数を定義することの意義について考察します。
Traceback (most recent call last): File "未定義の関数を参照しようとすると、例外 NameError を生成して、エラーメッセージが出力されます。これは「関数の名前(識別子)が未定義である」ことを意味します。この状況は、未定義の変数と同じです。", line 1, in piyo NameError: name 'piyo' is not defined 《tips》変数は、それによって束縛されるオブジェクトとは独立した概念です。そのため、対象となるオブジェクト(整数、関数、クラスなど)には依存しない、共通の操作が可能になります。関数オブジェクト
関数オブジェクトは、リテラル表現を持たないので、それを参照する術がありません。変数は、任意の「関数」オブジェクトを参照する手段を提供します。>>> def piyo(): pass #3: >>> id(piyo) 19044008 >>> def piyo(): pass #4: >>> id(piyo) 19227896 >>> type(piyo) <class 'function'>同じコード(関数の本体)を持つ、関数 piyo を再定義します。このとき、どのようなオブジェクトが生成されては、解放されるのでしょうか。■ #3: 関数を定義する
(関数の名前と同じ)変数 piyo は、関数オブジェクト(id:19044008)を参照する手段を提供します。■ #4: 関数を再定義する
変数 piyo の束縛を解いて、ある関数オブジェクト(id:19044008)を解放します。すると、変数 piyo を介して、別の関数オブジェクト(id:19227896)を参照できるようになります。つまり、関数(メソッド)を再定義するということは、旧い関数オブジェクトへの束縛を解いて「新たな関数オブジェクトと関連を結ぶ」ことを意味します。 2つの関数オブジェクトは、どちらも同じコード(関数の本体)を持ちますが、それぞれに異なるオブジェクトです。そのため、変数 piyo を介して得られる機能は同じですが、それを実現するのは異なる関数オブジェクトです。《note》変数による束縛:関数と同じ名前の変数を介して「関数」オブジェクトを参照する様子は、変数によって「整数」オブジェクトを参照する場合と同じです。関数オブジェクトはリテラル表現を持たないので、生成した関数オブジェクトを参照するには、変数を利用するしか術がありません。変数によって束縛されていない関数オブジェクトは、やがて回収される運命にあります。lambda 式は、名前を持たない関数オブジェクトを参照する、直接的な手段を提供します。式は(lambda 式に限らず)リテラル表現に代えて、オブジェクトを参照する手段のひとつを提供します。例えば、》こちらに移動中です《 ↑TOP>>> id(7) 3483872 >>> id(3+4) 3483872リテラル表現 7 と式 3+4 とは、どちらも同じ「整数」オブジェクト 7(id:3483872)を参照します。このように、オブジェクトを参照(表現)するには、次の3つの手段があります。
- リテラル
- 変数
- 式
《oops》Python3.1 の隘路:純粋な OOP に反する不純な側面
>>> 3.__add__(4) # (x.x) ... too bad SyntaxError: invalid syntax (残念ながら、Python3.1 では、リテラル表現(整数オブジェクト)に対するメソッド呼び出しは、構文規則に違反すると見なされ、例外 SyntaxError を生成します。リテラル表現(実数オブジェクト)に対するメソッド呼び出しは有効です。この問題を解消するために変数を利用できますが、他の「純粋な OOP 言語」と肩を並べるために、Python が越えなければならない壁のひとつです。, line 1) >>> 3.0.__add__(4) 7.0 >>> n = 3 >>> n.__add__(4) 7 《note》詳細は、中級編「ソースコードの歩き方」で解説します。