グローバル変数とローカル変数
次のプログラムを実行すればどのように出力されるでしょうか。
x = 1
def foo():
x = 2
print(x)
foo()
print(x)
答えは次の通りです。
2 1
関数の外で定義された x = 1 はグローバル変数で、プログラム全体で有効です。これに対して、関数の中で定義された x = 2 はローカル変数で、関数の中でしか有効でありません。両者はまったく別物なので、関数の中でローカル変数に代入しても、グローバル変数は変わりません。
関数の中でグローバル変数を使うには、次のようにします。
x = 1
def foo():
global x
x = 2
print(x)
foo()
print(x)
この出力は次の通りです。
2 2
関数の中の x はグローバル変数になり、関数の外のものと同じものになりました。
次はどうでしょうか。
x = 1
def foo():
print(x)
foo()
print(x)
この出力は次の通りです。
1 1
関数の中で global x しませんでしたが、この場合は関数の中では x を参照しているだけですので、グローバルの x の値を出力します。
では、次はどうでしょうか。
x = 1
def foo():
print(x)
x = 2
foo()
print(x)
UnboundLocalError: cannot access local variable 'x' where it is not associated with a value
エラーになってしまいました。これは関数の中で x の値を変えようとしたため、関数全体で x がローカル変数になり、関数の中で print(x) した時点ではローカル変数に値が入っていないので、エラーになったのです。
これは気をつけないといけないバグの元で、特に
x = 1
def foo():
print(x)
# ほかの処理
# ほかの処理
x = 2
のようにずっと後の方で代入してしまった場合にも、遡って関数の最初の print(x) でエラーになるので、注意が必要です。
なお、この例は、「インタプリタは1行ずつ解釈して実行する」という俗説の反例にもなっています。実際には、現代のインタプリタは全部をコンパイルしてから実行しますので、ずっと後の部分が前の部分に影響することがありえます。