Python を学習している多くの人々 (「割り当て前に参照」式を使用して stackoverflow.com で調査を行ってください) のように、あなたが持っていた理解不能と驚きは、ドキュメンテーションが時々ひどく書かれているという事実によるものです。
このエラーの説明は次のとおりです。
コード ブロック内の任意の場所で名前バインディング操作が発生した場合、ブロック内の名前のすべての使用は、現在のブロックへの参照として扱われます。これは、名前がバインドされる前にブロック内で使用されると、エラーを引き起こす可能性があります。このルールは微妙です。Python には宣言がなく、コード ブロック内の任意の場所で名前バインディング操作を実行できます。コード ブロックのローカル変数は、ブロックのテキスト全体をスキャンして名前バインディング操作を行うことによって決定できます。
http://docs.python.org/2/reference/executionmodel.html
私の意見では、この抜粋は、コードが実行されたときに実行されることをうまく表現していません。「スキャンによって判断できる
」と言うのは欺瞞であり、このスキャンはオプションであるという印象を与えます。
この点について私の意見を確認するようなものを読んだことはありませんが、個人的には次のように考えています:
- 実際、このスキャンは常に実行されますが、それはオプションではありません
- さらに重要なことに、このスキャンは呼び出し可能なオブジェクトの呼び出しの前に行われますブロックが定義していること
.
実際、最初に理解しておくべき重要な概念があります。
呼び出し可能なオブジェクトの定義は、オブジェクトが呼び出される前に行われます
「定義」という用語は、次の 2 つの方法で理解できるため、あいまいであることを認識する必要があります
。1/ 定義 = 何かを「定義」するスクリプト内のコード ブロック
2/ 定義 = 実行時のこのコード ブロックの実行定義された呼び出し可能オブジェクトを作成するスクリプトの
私はこれらの主張に基づいています:
ブロックは、ユニットとして実行されるPython プログラムテキストの一部です。ブロックとは、モジュール、関数本体、およびクラス定義です。
http://docs.python.org/2/reference/executionmodel.html
.
関数定義は、ユーザー定義の関数オブジェクトを定義します (...)
関数定義 [センス 1] は、実行可能なステートメントです。その実行は、現在のローカル名前空間の関数名を関数オブジェクトにバインドします (...)関数定義 [センス 2] は関数本体を実行
しません。これは、関数が呼び出されたときにのみ実行されます。
http://docs.python.org/2/reference/compound_stmts.html#function-definitions
.
A function definition defines a user-defined function object
: とても美しいトートロジー! この文は何も説明していません。
[センス 1] では、「定義」は「定義するコード ブロック (=テキスト)」を意味します[
センス 2] では、「定義」は「定義するコード ブロックの実行」を意味します。テキスト (定義の意味 1) は何も実行せず、テキストとして受動的に嘘をつきます...
「定義」という名前があいまいで、ドキュメントが時々ひどく書かれていることがわかります.....
最後の抽出は関数定義に関するものですが、その概念は明らかにクラスや他の呼び出し可能なオブジェクトに拡張できます。クラスはコード ブロックによっても定義され、定義 (センス 2 = 定義するコード ブロックの実行) と呼び出しの 2 つのステップが存在します。
.
したがって、私の主張は、呼び出し可能なオブジェクト内の識別子のスキャンとそのスコープの決定は、コード ブロック [= 定義センス 1] が実行される瞬間に実行されると考えるように確立されているということです。この実行は、いわゆる "定義」[センス2]も。
それが私の意見の重要なポイントとして指摘したかったことです。
.
PS: ドキュメントの上記の抜粋での「変数」という用語の使用は、嘆かわしいことです。「変数」は、Python で使用される場合、別の非常にあいまいな用語だからです。
それが嘆かわしいことの証拠は、OPがJavaで何が起こるか、Pythonで何が起こるかを比較して彼の質問を提示することです。
基本的な公式ドキュメントのどこかに、Python ではコーダーが「コンテンツが変更される可能性のあるメモリのチャンク」として機能するエンティティにアクセスできないという事実の確固たる説明があった場合、この種の混乱はめったに起こらないはずです。
でもそれはまた別の話