4. 実行モデル—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/2.7/reference/executionmodel
移動先:案内検索

4.4。 実行モデル

4.1。 ネーミングとバインディング

名前はオブジェクトを参照します。 名前は、名前バインディング操作によって導入されます。 プログラムテキスト内の名前の各出現は、使用を含む最も内側の機能ブロックで確立されたその名前のバインディングを参照します。

ブロックは、ユニットとして実行されるPythonプログラムテキストの一部です。 ブロックは次のとおりです。モジュール、関数本体、およびクラス定義。 インタラクティブに入力される各コマンドはブロックです。 スクリプトファイル(インタプリタへの標準入力として指定されるファイル、またはインタプリタのコマンドラインで最初の引数に指定されるファイル)は、コードブロックです。 スクリプトコマンド(インタプリタコマンドラインで「 -c 」オプションを指定して指定されたコマンド)は、コードブロックです。 組み込み関数 execfile()によって読み取られるファイルはコードブロックです。 組み込み関数 eval()および exec ステートメントに渡される文字列引数はコードブロックです。 組み込み関数 input()によって読み取られて評価される式は、コードブロックです。

コードブロックは実行フレームで実行されます。 フレームには(デバッグに使用される)いくつかの管理情報が含まれ、コードブロックの実行が完了した後、実行をどこでどのように続行するかを決定します。

scope は、ブロック内の名前の可視性を定義します。 ローカル変数がブロックで定義されている場合、そのスコープにはそのブロックが含まれます。 定義が関数ブロックで発生する場合、含まれているブロックが名前に異なるバインディングを導入しない限り、スコープは定義ブロック内に含まれているすべてのブロックに拡張されます。 クラスブロックで定義されている名前のスコープは、クラスブロックに限定されています。 メソッドのコードブロックには拡張されません。これには、関数スコープを使用して実装されるため、ジェネレーター式が含まれます。 これは、以下が失敗することを意味します。

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

コードブロックで名前が使用されている場合、最も近い囲みスコープを使用して名前が解決されます。 コードブロックに表示されるこのようなすべてのスコープのセットは、ブロックの環境と呼ばれます。

名前がブロックにバインドされている場合、それはそのブロックのローカル変数です。 名前がモジュールレベルでバインドされている場合、それはグローバル変数です。 (モジュールコードブロックの変数はローカルおよびグローバルです。)変数がコードブロックで使用されているが、そこで定義されていない場合、それは自由変数です。

名前がまったく見つからない場合、NameError例外が発生します。 名前がバインドされていないローカル変数を参照している場合、UnboundLocalError例外が発生します。 UnboundLocalErrorNameErrorのサブクラスです。

次の構成は名前をバインドします:関数への仮パラメーター、 import ステートメント、クラスと関数の定義(これらは定義ブロック内のクラスまたは関数名をバインドします)、および割り当てで発生する場合は識別子であるターゲット、[ X255X] for ループヘッダー、 exception 句ヘッダーの2番目の位置、または with ステートメントの as の後。 from ... import *形式の import ステートメントは、アンダースコアで始まる名前を除き、インポートされたモジュールで定義されたすべての名前をバインドします。 このフォームは、モジュールレベルでのみ使用できます。

del ステートメントで発生するターゲットも、この目的にバインドされていると見なされます(ただし、実際のセマンティクスは名前のバインドを解除することです)。 囲んでいるスコープによって参照されている名前のバインドを解除することは違法です。 コンパイラはSyntaxErrorを報告します。

各割り当てまたはインポートステートメントは、クラスまたは関数の定義によって定義されたブロック内、またはモジュールレベル(最上位のコードブロック)で発生します。

コードブロック内のどこかで名前バインディング操作が発生した場合、ブロック内での名前の使用はすべて、現在のブロックへの参照として扱われます。 これにより、名前がバインドされる前にブロック内で使用されると、エラーが発生する可能性があります。 このルールは微妙です。 Pythonには宣言がなく、名前バインディング操作をコードブロック内のどこでも実行できます。 コードブロックのローカル変数は、ブロックのテキスト全体をスキャンして名前バインディング操作を行うことで判別できます。

グローバルステートメントがブロック内で発生する場合、ステートメントで指定された名前のすべての使用は、最上位の名前空間でのその名前のバインディングを参照します。 名前は、グローバル名前空間を検索することにより、最上位の名前空間で解決されます。 コードブロックを含むモジュールの名前空間、および組み込みの名前空間、モジュールの名前空間 __ builtin __ 。 グローバル名前空間が最初に検索されます。 名前がそこに見つからない場合は、組み込みの名前空間が検索されます。 グローバルステートメントは、名前のすべての使用の前に置く必要があります。

コードブロックの実行に関連付けられている組み込みの名前空間は、実際には、グローバル名前空間で__builtins__という名前を検索することで見つかります。 これは辞書またはモジュールである必要があります(後者の場合、モジュールの辞書が使用されます)。 デフォルトでは、 __ main __ モジュールの場合、__builtins__は組み込みモジュール __ builtin __ です(注:「s」はありません)。 他のモジュールの場合、__builtins____ builtin __ モジュール自体の辞書のエイリアスです。 __builtins__をユーザー作成辞書に設定して、弱い形式の制限付き実行を作成できます。

モジュールの名前空間は、モジュールが最初にインポートされたときに自動的に作成されます。 スクリプトのメインモジュールは常に __ main __ と呼ばれます。

global ステートメントは、同じブロック内の名前バインディング操作と同じスコープを持っています。 自由変数の最も近い囲みスコープにグローバルステートメントが含まれている場合、自由変数はグローバルとして扱われます。

クラス定義は、名前を使用および定義できる実行可能ステートメントです。 これらの参照は、名前解決の通常の規則に従います。 クラス定義の名前空間は、クラスの属性ディクショナリになります。 クラススコープで定義された名前は、メソッドに表示されません。

4.1.1。 動的機能との相互作用

自由変数を含むネストされたスコープと組み合わせて使用すると、Pythonステートメントが不正な場合がいくつかあります。

変数が囲んでいるスコープで参照されている場合、その名前を削除することは違法です。 コンパイル時にエラーが報告されます。

ワイルドカード形式のインポート(import *)が関数で使用され、関数に自由変数が含まれるかネストされたブロックである場合、コンパイラーはSyntaxErrorを生成します。

exec が関数で使用され、関数に自由変数が含まれるかネストされたブロックである場合、execがのローカル名前空間を明示的に指定しない限り、コンパイラはSyntaxErrorを生成します。 exec 。 (つまり、exec objは違法ですが、exec obj in nsは合法です。)

eval()execfile()、および input()関数と exec ステートメントは完全な環境にアクセスできません名前を解決するため。 名前は、呼び出し元のローカルおよびグローバル名前空間で解決される場合があります。 自由変数は、最も近い囲んでいる名前空間ではなく、グローバル名前空間で解決されます。 1 exec ステートメントと eval()および execfile()関数には、グローバルおよびローカル名前空間をオーバーライドするオプションの引数があります。 名前空間が1つだけ指定されている場合は、両方に使用されます。


4.2。 例外

例外は、エラーやその他の例外的な状態を処理するために、コードブロックの通常の制御フローから抜け出す手段です。 例外は、エラーが検出された時点での発生です。 周囲のコードブロック、またはエラーが発生したコードブロックを直接または間接的に呼び出したコードブロックによって処理される可能性があります。

Pythonインタープリターは、実行時エラー(ゼロ除算など)を検出すると例外を発生させます。 Pythonプログラムは、 raise ステートメントを使用して明示的に例外を発生させることもできます。 例外ハンドラーは、 tryexcept ステートメントで指定されます。 このようなステートメントの finally 句を使用して、例外を処理しないクリーンアップコードを指定できますが、前のコードで例外が発生したかどうかに関係なく実行されます。

Pythonはエラー処理の「終了」モデルを使用します。例外ハンドラーは何が起こったのかを見つけて外部レベルで実行を続行できますが、エラーの原因を修復して失敗した操作を再試行することはできません(問題のある部分を再入力する場合を除く)上からのコードの)。

例外がまったく処理されない場合、インタプリタはプログラムの実行を終了するか、インタラクティブなメインループに戻ります。 いずれの場合も、例外がSystemExitの場合を除いて、スタックバックトレースを出力します。

例外はクラスインスタンスによって識別されます。 exception 句は、インスタンスのクラスに応じて選択されます。インスタンスのクラスまたはその基本クラスを参照する必要があります。 インスタンスはハンドラーが受け取ることができ、例外条件に関する追加情報を運ぶことができます。

例外は文字列で識別することもできます。その場合、 exception 句はオブジェクトIDによって選択されます。 ハンドラーに渡すことができる識別文字列とともに、任意の値を上げることができます。

ノート

例外へのメッセージはPythonAPIの一部ではありません。 それらの内容は、警告なしにPythonのバージョンごとに変更される可能性があるため、複数のバージョンのインタープリターで実行されるコードに依存しないでください。


セクション tryステートメントtry ステートメントおよびセクション raiseステートメントraise ステートメントの説明も参照してください。

脚注

1
この制限は、これらの操作によって実行されるコードが、モジュールのコンパイル時に使用できないために発生します。