Pythonで変数を扱う際に、次のようなエラーに遭遇したことはありませんか?
|
1 |
UnboundLocalError: local variable 'x' referenced before assignment |
このエラーは、関数内で変数を参照しようとした際に、Pythonが「その変数はまだローカルで定義されていない」と判断したときに発生します。
目次
UnboundLocalError: local variable referenced before assignment とは何か
このエラーは、関数内の変数を参照する前に、Python が「その変数はローカル変数だが、割り当てがされていない」と判断した場合に発生します。つまり、関数のスコープ内で変数を参照しようとした時、意図せずローカル変数として扱われてしまったパターンです。
なぜエラーが起きるのか(主な原因)
代表的な原因は以下の通りです:
- 関数内でグローバル変数と同じ名前の変数に代入しようとしている
- ローカル変数の代入前に読み込みを行っている
- 関数内で非local・非global変数を参照している
よくある間違いコード例と問題点
例1:グローバル変数を参照しようとして発生
問題のあるコード:
|
1 2 3 4 5 |
counter = 0 def increment(): print(counter) # UnboundLocalError counter += 1 |
この場合、関数内で counter += 1 としているため、Python は counter をローカル変数とみなします。そのため、print(counter) 時点では未初期化のローカル変数として扱われ、エラーが発生します。
例2:代入前に参照しているパターン
問題のあるコード:
|
1 2 3 4 |
def func(): if flag: value = 10 print(value) |
ここでは、flag が False の場合に value が定義されないまま参照され、UnboundLocalError が出ます。
対処法と修正パターン
以下の修正方法を使えば、問題は解決できます:
方法①:global 宣言を使ってグローバル変数を明示する
先ほどの counter 例を修正:
|
1 2 3 4 5 6 |
counter = 0 def increment(): global counter print(counter) counter += 1 |
方法②:ローカル変数のみで完結させる
関数内で変数を完結させ、外部変数に依存しないようにします。
|
1 2 3 4 5 |
def increment(counter): print(counter) return counter + 1 counter = increment(counter) |
方法③:nonlocal キーワードを使う(ネスト関数の場合)
ネストされた関数で外側のスコープの変数を操作する場合に有効です。
|
1 2 3 4 5 6 7 |
def outer(): count = 0 def inner(): nonlocal count count += 1 print(count) inner() |
global と nonlocal の正しい使い方
用途に応じて以下を使い分けましょう:
- global: モジュールレベルのグローバル変数を関数内部で読み書きする
- nonlocal: ネストした関数間で外側スコープの変数を操作する
UnboundLocalError 防止のチェックリスト
コードレビューや開発時に以下の項目を確認しましょう。
- 関数内で代入している変数名はグローバル変数と衝突していないか?
- ローカル変数に代入前に参照していないか?
- 必要に応じて global や nonlocal を使っているか?
- ネスト関数を使っている場合、スコープの変数宣言を確認しているか?
よくある質問と補足情報
Q. Python のバージョンによってエラー表示は変わる?
A. 本エラーのメッセージ自体はバージョン間で大きく変更されていませんが、Python 2 と Python 3 でスコープの仕様に微妙な違いがあります。
Q. 関数の引数として渡せば常に安全?
A. 多くの場合関数引数を使うと安全ですが、mutable なデフォルト引数には注意が必要です。
Q. クラス内メソッドでもこのエラーは起きる?
A. クラス内でも同様の問題が発生します。特にメソッドでインスタンス変数とローカル変数を同名で使うと混乱を招きます。
UnboundLocalError は、Python のスコープルールを正しく理解していないと頻出する典型的なエラーです。global や nonlocal キーワードを適切に使い、明確な変数設計をすることで防ぐことができます。本記事を参考に、エラーのない堅牢な Python コードを目指してください。


