UnboundLocalError: グローバル変数の再代入で発生するエラー
概要
Pythonで関数内からグローバル変数を参照した後に再代入しようとすると、UnboundLocalError: cannot access local variable 'x' where it is not associated with a value が発生する。Pythonは関数内で変数への代入文があると、その変数を関数スコープ全体でローカル変数として扱うため、代入前の参照がエラーになる。
エラーメッセージ
Traceback (most recent call last):
File "example.py", line 8, in <module>
increment()
File "example.py", line 5, in increment
print(counter)
^^^^^^^
UnboundLocalError: cannot access local variable 'counter' where it is not associated with a value
Python 3.12以前では以下のメッセージになる:
UnboundLocalError: local variable 'counter' referenced before assignment
原因
関数内でのグローバル変数への再代入: Pythonのスコープルールにより、関数内に
x = ...という代入文があると、その関数全体でxはローカル変数として扱われる。代入文より前にxを参照すると、まだ値が束縛されていないローカル変数を読み取ることになりエラーとなる。複合代入演算子(
+=,-=など)の使用:counter += 1はcounter = counter + 1と等価であり、右辺のcounterの読み取り時点でローカル変数がまだ未束縛のためエラーとなる。条件分岐内での代入:
ifブロック内でのみ変数を代入し、elseブロックや後続コードで参照する場合、条件が成立しなかったパスでUnboundLocalErrorが発生する。
解決策
1. global宣言を使う
関数内でグローバル変数を変更する場合、global 宣言を関数の先頭に記述する。
| |
2. 引数と戻り値で受け渡す(推奨)
global の多用は可読性を下げる。関数の引数と戻り値で値を受け渡す設計が望ましい。
| |
3. nonlocalを使う(ネストされた関数)
クロージャ内で外側の関数の変数を変更する場合は nonlocal を使用する。
| |
4. ミュータブルなオブジェクトを使う
リストや辞書などのミュータブルオブジェクトは、参照自体の再代入ではなく内容の変更であれば global 宣言なしでも可能。
| |
5. 条件分岐での未束縛を防ぐ
| |
関連エラー
関連エラー
python の他のエラー
この記事は役に立ちましたか?