2016-08-05 9 views
2

変数がPythonによって内部的にどのように管理されているかを理解しようとしています。UnboundLocalErrorのPython到達不能変数の割り当て

x = 10 
def ex1(): 
    if False: 
     x=1 
    print(x) 
ex1() 

ex1()を実行すると、ローカル変数 'x'が参照されていないため、UnboundLocalErrorが表示されます。

どうしますか? 最初のパスで構文解析が行われ、シンボルテーブルを作成してスコープを指定した後、別のパスで解釈が行われ、到達できないためスキップします(x=1)。

+0

を。 –

答えて

0

Pythonには変数宣言がありません。したがって、変数を作成または使用するときは、スコープ自体を決定する必要があります。 Pythonスコープはレキシカルなので、囲まれたスコープ内の変数にアクセスでき、変更することはできません。 ex1()を書く方法は、x = 1はex1()に対してローカルです。しかし、ex1()を実行するとx = 10をローカルとして読み込み、UnboundLocalErrorをスローします。 したがって、変数が管理される方法は、ローカル宣言を見て、関数を実行し、別のローカル宣言を参照し、スコープのために2つを関連付けることはできません。

0

これは概念的に意味があります。私はそれがどのように実装されているかはわかりませんが、私はその理由を伝えます

変数に影響を与えると、キーワードglobalを使用して明示的に指示しない限り、ローカルスコープで影響を受けます。アクセスするだけで影響がない場合、ローカル変数が定義されていないため、暗黙的にグローバル変数が使用されます。あなたがネストされた関数、クラス、またはモジュール内これを行う場合は

x = 10 

def access_global(): 
    print x 

def affect_local(): 
    x = 0 
    print x 

def affect_global(): 
    global x 
    x = 1 
    print x 

access_global() # 10 
affect_local() # 0 
print x   # 10 
affect_global() # 1 
print x   # 10 

ルールは似ています。

def main(): 
    y = 10 
    def access(): 
     print y 
    def affect(): 
     y = 0 
     print y 

    access() # 10 
    affect() # 0 
    print y # 10 

main() 

これはおそらく、親スコープの決して上書きしない変数によって痛みを伴うデバッグの時間を節約されて、明示的に述べない限り。

EDIT

Pythonのバイトコードを逆アセンブルすることは理解することが私たちにいくつかの追加情報を提供します:

import dis 
x = 10 
def local(): 
    if False: 
     x = 1 

def global_(): 
    global x 
    x = 1 

print local 
dis.dis(local) 
print global_ 
dis.dis(global_) 


<function local at 0x7fa01ec6cde8> 
37   0 LOAD_GLOBAL    0 (False) 
       3 POP_JUMP_IF_FALSE  15 

38   6 LOAD_CONST    1 (1) 
       9 STORE_FAST    0 (x) 
      12 JUMP_FORWARD    0 (to 15) 
     >> 15 LOAD_CONST    0 (None) 
      18 RETURN_VALUE   
<function global_ at 0x7fa01ec6ce60> 
42   0 LOAD_CONST    1 (1) 
       3 STORE_GLOBAL    0 (x) 
       6 LOAD_CONST    0 (None) 
       9 RETURN_VALUE  

我々はlocal関数のバイトコードがSTORE_FASTを呼び出していることがわかりますとglobal_関数呼び出しSTORE_GLOBAL

この質問はまた、理由を説明、その関数が呼び出されるたびにコンパイルを避けるために、バイトコードへの機能を翻訳するよりパフォーマンス:正しい Why python compile the source to bytecode before interpreting?

関連する問題