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


4.1. プログラムの構造
=====================

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

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


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


4.2.1. 名前の束縛
-----------------

*名前 (name)* は、オブジェクトを参照します。名前を導入するには、名前へ
の束縛 (name binding) 操作を行います。

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

"del" 文で指定される対象は、("del" の意味付けは、実際は名前の解放
(unbind) ですが) 文の目的上、束縛済みのものとみなされます。

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

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

プログラムテキスト中に名前が出現するたびに、その名前が使われている最も
内側の関数ブロック中で作成された *束縛 (binding)* を使って名前の参照が
行われます。


4.2.2. 名前解決
---------------

スコープ (*scope*) は、ブロック内の名前の可視性を決めます。 ローカル変
数があるブロック内で定義されている場合、変数のスコープはそのブロックを
含みます。 関数ブロック内で名前の定義を行った場合、その中のブロックが
名前に別の束縛を行わない限り、定義ブロック内の全てのブロックを含むよう
にスコープが拡張されます。

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

名前が全く見付からなかったときは、 "NameError" 例外が送出されます。 現
在のスコープが関数のもので、名前が使われる場所でローカル変数がまだ値に
束縛されていない場合、 "UnboundLocalError" 例外が送出されます。
"UnboundLocalError" は "NameError" の子クラスです。

ある名前がコードブロック内のどこかで束縛操作されていたら、そのブロック
内で使われるその名前はすべて、現在のブロックへの参照として扱われます。
このため、ある名前がそのブロック内で束縛される前に使われるとエラーにつ
ながります。この規則は敏感です。Python には宣言がなく、コードブロック
のどこでも名前束縛操作ができます。あるコードブロックにおけるローカル変
数は、ブロックのテキスト全体から名前束縛操作を走査することで決定されま
す。

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

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

"nonlocal" 文によって、対応する名前が最内関数スコープでそれ以前に束縛
された変数を参照するようになります。もし名前がどの最内関数スコープにも
存在しなければ、コンパイル時に "SyntaxError" が上げられます。

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

クラス定義ブロックと "exec()" や "eval()" に対する引数は、名前解決の文
脈で特別です。クラス定義は、名前を使うことと定義することができる実行可
能な文です。これらの参照は、名前解決のための通常のルールに従いますが、
束縛されていないローカル変数がグローバルな名前空間から検索されるという
例外があります。クラス定義の名前空間はクラスの属性辞書になります。クラ
ス内で定義された名前のスコープは、クラスのブロックに限定されます; メソ
ッドのコードブロックには拡張されません。 -- 内包表記やジェネレータ式も
関数スコープを利用して実装されているので、スコープの拡張範囲外です。つ
まり、次のようなコードは失敗します:

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


4.2.3. 組み込みと制限付きの実行
-------------------------------

**CPython implementation detail:** ユーザは "__builtins__" に触れるべ
きではありません; これは厳密に実装の詳細です。組み込みの名前空間の中の
値をオーバーライドしたいユーザは、 "builtins" モジュールを "import" し
て、その属性を適切に変更するべきです。

あるコードブロックの実行に関連する組み込み名前空間は、実際にはコードブ
ロックのグローバル名前空間から名前 "__builtins__" を検索することで見つ
かります; "__builtins__"  は辞書かモジュールでなければなりません (後者
の場合はモジュールの辞書が使われます)。デフォルトでは、 "__main__" モ
ジュール中においては、 "__builtins__" は組み込みモジュール "builtins"
です; それ以外の任意のモジュールにおいては、 "__builtins__" は
"builtins" モジュール自身の辞書のエイリアスです。


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

自由変数の名前解決はコンパイル時でなく実行時に行われます。つまり、以下
のコードは42を出力します:

   i = 10
   def f():
       print(i)
   i = 42
   f()

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


4.3. 例外
=========

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

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

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

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

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

注釈:

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

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

-[ 脚注 ]-

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