4. 実行モデル
*************


4.1. 名前づけと束縛 (naming and binding)
========================================

*名前 (name)* とは、オブジェクトを参照するものを指します。名前への束縛
(name binding) 操作を行うと、名前を導入できます。プログラムテキスト中
に名前が出現するたびに、その名前が使われている最も内側の関数ブロック中
で作成された *束縛 (binding)* を使って名前の参照が行われます。

ブロック (*block*) は、 Python のプログラムテキストからなる断片で、一
つの実行単位となるものです。モジュール、関数本体、そしてクラス定義はブ
ロックです。また、対話的に入力された個々のコマンドもブロックです。スク
リプトファイル ( インタプリタに標準入力として与えたり、コマンドライン
の第一引数として指定したファイル ) は、コードブロックです。スクリプト
コマンド ( インタプリタのコマンドライン上で '**-c**' オプションを使っ
て指定したコマンド ) もコードブロックです。組み込み関数 "eval()" や
"exec" 文に渡した文字列もコードブロックになります。組み込み関数
"input()" から読み取られ、評価される式もまた、コードブロックです。

コードブロックは、実行フレーム(*execution frame*) 上で実行されます。実
行フレームには、 (デバッグに使われる) 管理情報が収められています。また
、現在のコードブロックの実行が完了した際に、どのようにプログラムの実行
を継続するかを決定しています。

スコープ (*scope*) は、ある名前があるブロック内で参照できるかどうかを
決めます。ローカル変数があるブロック内で定義されている場合、変数のスコ
ープはそのブロックを含みます。関数ブロック内で名前の定義を行った場合、
その名前に対して別の束縛を行っているブロックを除いた、関数内の全てのブ
ロックを含むようにスコープが拡張されます。クラス内で定義された名前のス
コープは、クラスのブロック内に制限されます ; スコープがメソッドのコー
ドブロックを含むよう拡張されることはありません。 -- ジェネレータ式も関
数スコープを利用して実装されているのでスコープの拡張範囲外です。つまり
、次のようなコードは失敗します。

   class A:
       a = 42
       b = list(a + i for i in range(10))

ある名前がコードブロック内で使われると、その名前を最も近傍から囲うよう
なスコープ (最内スコープ: nearest enclosing scope) を使って束縛の解決
を行います。こうしたスコープからなる、あるコードブロック内で参照できる
スコープ全ての集合は、ブロックの環境(*environment*)と呼ばれます。

ある名前がブロック内で束縛されている場合、名前はそのブロックにおけるロ
ーカル変数 (local variable) です。ある名前がモジュールレベルで束縛され
ている場合、名前はグローバル変数 (global variable) です。 ( モジュール
コードブロックの変数は、ローカル変数でもあるし、グローバル変数でもあり
ます。 ) ある変数がコードブロック内で使われているが、そのブロックでは
定義されていない場合、変数は自由変数 (*free variable*) です。

ある名前の定義がどこにもない場合、 "NameError" 例外が送出されます。名
前がまだ束縛されていないローカルな変数を参照した場合、
"UnboundLocalError" 例外が送出されます。 "UnboundLocalError" は、
"NameError" のサブクラスです。

名前への束縛は、以下の文構成 (construct) で行われます : 関数の仮引数
(formal parameter) 指定、 "import" 文、クラスや関数の定義 ( 定義を行っ
たブロック中で、クラスや関数名の束縛が行われます ) 、代入時に代入対象
が識別子である場合、 "for" ループのヘッダ、 "except" 文ヘッダの第二要
素、 "with" 文の中の "as" の後ろ。 ""from...import *"" 形式の import
文は、 import しようとするモジュール内で定義されている名前について、ア
ンダースコアから始まっている名前以外の全てを束縛します。この形式は、モ
ジュールレベルでしか使うことができません。

"del" 文で指定された対象は、 ("del" の意味付けは、実際は名前の解放
(unbind) ですが ) 文の目的上、束縛済みのものとみなされます。外側のスコ
ープで参照されている名前の解放は、不正な操作になります ; コンパイラは
"SyntaxError" を報告するでしょう。

代入文や import 文はいずれも、クラスや関数定義、モジュールレベル (トッ
プレベルのコードブロック) 内で起こります。

ある名前束縛操作がコードブロック内のどこかにある場合、ブロック内でその
名前を使うと、全て現在のブロックで束縛されている名前を指すものとみなさ
れます。このため、ある名前が束縛される前にブロック内で使われるとエラー
を引き起こす可能性があります。この規則はやや微妙です。 Python には宣言
文がなく、コードブロックのどこで名前束縛操作を行ってもかまいません。あ
るコードブロックにおけるローカル変数は、ブロック全体から名前束縛操作が
行われている部分を走査して決定します。

global 文で指定された名前がブロック内にある場合、その名前は常にトップ
レベルの名前空間で束縛された名前を参照します。それらの名前はグローバル
名前空間、すなわちコードブロックが収められているモジュールの名前空間と
モジュール名 "__builtin__" で表される組み込み名前空間、を検索すること
によって、トップレベルの名前空間で解決されます。グローバル名前空間は、
常に最初に検索されます。名前がグローバル名前空間中に見つからない場合、
組み込み名前空間が検索されます。 global 文は、その名前が使われている全
ての文に先立って記述されていなければなりません。

あるコードブロックの実行時に関連付けられる組み込み名前空間は、実際には
コードブロックのグローバル名前空間内に入っている名前 "__builtins__" を
参照する形になっています ; "__builtins__" は辞書かモジュール ( 後者の
場合にはモジュールの辞書が使われます ) でなければなりません。デフォル
トで "__main__" モジュール中においては、 "__builtins__" は組み込みモジ
ュール "__builtin__" です ( 注意 : 's' なし ) ；それ以外のモジュールで
は、 "__builtins__" は "__builtin__" モジュールそれ自身の辞書のエイリ
アスです。 "__builtins__" はユーザが作成した辞書を設定して、弱い形態の
制限実行を作成することが可能です。

ユーザは "__builtins__" に触れるべきではありません；これはくれぐれも実
装の詳細であるのです。組み込みの名前空間の中の値をオーバーライドしたい
ユーザは、 "__builtin__" ('s' はありません ) モジュールを "import" し
て、その属性を好きに変更するべきです。

あるモジュールの名前空間は、そのモジュールが最初に import された時に自
動的に作成されます。スクリプトの主モジュール (main module) は常に
"__main__" と呼ばれます。

"global" 文は、同じブロックの束縛操作と同じスコープを持ちます。ある自
由変数の最内スコープに global 文がある場合、その自由変数はグローバル変
数とみなされます。

クラス定義は一つの実行文で、名前の使用や定義を行います。クラス定義への
参照は、通常の名前解決規則に従います。クラス定義の名前空間は、そのクラ
スの属性辞書になります。クラスのスコープで定義された名前は、メソッドか
らは見えません。


4.1.1. 動的な機能とのやりとり
-----------------------------

自由変数のある入れ子のスコープを併用すると、Python の文が不正になる場
合がいくつかあります。

ある変数がスコープの外側から参照された場合、その名前に対する削除操作は
不正になります。この場合、コンパイル時にエラーが報告されることになりま
す。

ワイルドカード形式の import 文 --- "import *" --- を関数内で使った場合
や、関数が自由変数を含んでいたり、自由変数を伴う入れ子ブロックである場
合、コンパイラは "SyntaxError" を送出します。

"exec" が関数内で使われており、関数が自由変数を含んでいたり、自由変数
を伴う入れ子ブロックである場合、 "exec" に明示的にローカル名前空間を指
定しないかぎりコンパイラは SyntaxError を送出します。 ( 別の言い方をす
れば、 "exec obj" は不正になることがあり、 "exec obj in ns" はならない
、ということです。 )

"eval()" 、 "execfile()" 、および "input()" 関数、そして "exec" 文は、
名前の解決を行う際に、現在の環境に対して完全にアクセスできるわけではあ
りません。名前が呼び出し側のローカル名前空間やグローバル名前空間から解
決されることはあります。自由変数は最内名前空間ではなく、グローバル名前
空間から解決されます。 [1] "exec" 文と、関数 "eval()" および
"execfile()" にはオプションの引数があり、グローバルおよびローカル名前
空間をオーバライドできます。名前空間を一つしか指定しなければ、両方の名
前空間として使われます。


4.2. 例外
=========

例外とは、コードブロックの通常の制御フローを中断して、エラーやその他の
例外的な状況を処理できるようにするための手段です。例外はエラーが検出さ
れた時点で *送出 (raise)* されます; 例外は、エラーが発生部の周辺のコー
ドブロックか、エラーが発生したコードブロック直接または間接的に呼び出し
ているコードブロックで *処理 (handle)* することができます。

Python インタプリタは、ランタイムエラー (ゼロによる除算など) が検出さ
れると例外を送出します。Python プログラムから、 "raise" 文を使って明示
的に例外を送出することもできます。例外ハンドラ (exception handler) は
、 "try" ... "except" 文で指定することができます。 "try" 文の
"finally" 節を使うとクリーンアップコード (cleanup code) を指定できます
。このコードは例外は処理しませんが、先行するコードブロックで例外が起き
ても起きなくても実行されます。

Python は、エラー処理に "プログラムの終了 (termination)" モデルを用い
ています: 例外ハンドラは、プログラムに何が発生したかを把握することがで
き、ハンドラの外側のレベルに処理を継続することはできますが、(問題のあ
ったコード部分を最初から実行しなおすのでない限り) エラーの原因を修復し
たり、実行に失敗した操作をやり直すことはできません。

例外が全く処理されない場合、インタプリタはプログラムの実行を終了させる
か、対話メインループに処理を戻します。どちらの場合も、例外が
"SystemExit" でない限りバックトレース (backtrace) を出力します。

例外は、クラスインスタンスによって識別されます。 "except" 節はインスタ
ンスのクラスにもとづいて選択されます: これはインスタンスのクラスか、そ
のベースクラスを参照します。このインスタンスはハンドラによって受け取ら
れ、例外条件に関する追加情報を伝えることができます。

例外は文字列 (strings) によっても識別することができ、このような場合に
は "except" 節はオブジェクトの同一性によって選択されます。任意の値をハ
ンドラに渡される識別文字列に伴って送出することができます。

注釈: 例外に対するメッセージは、 Python API 仕様には含まれていません
  。メッ セージの内容は、ある Python のバージョンから次のバージョンに
  なるとき に、警告なしに変更される可能性があります。したがって、複数
  バージョン のインタプリタで動作するようなコードにおいては、例外メッ
  セージの内容 に依存した記述をすべきではありません。

"try" 文については、 try 文 節、 "raise" 文については raise 文 節も参
照してください。

-[ 注記 ]-

[1] この制限は、上記の操作によって実行されるコードが、モジュールを
    コン パイルしたときには利用できないために起こります。
