UnboundLocalError: local variable referenced before assignment の対処法

Pythonで変数を扱う際に、次のようなエラーに遭遇したことはありませんか?

このエラーは、関数内で変数を参照しようとした際に、Pythonが「その変数はまだローカルで定義されていない」と判断したときに発生します。

目次

UnboundLocalError: local variable referenced before assignment とは何か

このエラーは、関数内の変数を参照する前に、Python が「その変数はローカル変数だが、割り当てがされていない」と判断した場合に発生します。つまり、関数のスコープ内で変数を参照しようとした時、意図せずローカル変数として扱われてしまったパターンです。

なぜエラーが起きるのか(主な原因)

代表的な原因は以下の通りです:

  • 関数内でグローバル変数と同じ名前の変数に代入しようとしている
  • ローカル変数の代入前に読み込みを行っている
  • 関数内で非local・非global変数を参照している

よくある間違いコード例と問題点

例1:グローバル変数を参照しようとして発生

問題のあるコード:

この場合、関数内で counter += 1 としているため、Python は counter をローカル変数とみなします。そのため、print(counter) 時点では未初期化のローカル変数として扱われ、エラーが発生します。

例2:代入前に参照しているパターン

問題のあるコード:

ここでは、flag が False の場合に value が定義されないまま参照され、UnboundLocalError が出ます。

対処法と修正パターン

以下の修正方法を使えば、問題は解決できます:

方法①:global 宣言を使ってグローバル変数を明示する

先ほどの counter 例を修正:

方法②:ローカル変数のみで完結させる

関数内で変数を完結させ、外部変数に依存しないようにします。

方法③:nonlocal キーワードを使う(ネスト関数の場合)

ネストされた関数で外側のスコープの変数を操作する場合に有効です。

global と nonlocal の正しい使い方

用途に応じて以下を使い分けましょう:

  • global: モジュールレベルのグローバル変数を関数内部で読み書きする
  • nonlocal: ネストした関数間で外側スコープの変数を操作する

UnboundLocalError 防止のチェックリスト

コードレビューや開発時に以下の項目を確認しましょう。

  1. 関数内で代入している変数名はグローバル変数と衝突していないか?
  2. ローカル変数に代入前に参照していないか?
  3. 必要に応じて global や nonlocal を使っているか?
  4. ネスト関数を使っている場合、スコープの変数宣言を確認しているか?

よくある質問と補足情報

Q. Python のバージョンによってエラー表示は変わる?
A. 本エラーのメッセージ自体はバージョン間で大きく変更されていませんが、Python 2 と Python 3 でスコープの仕様に微妙な違いがあります。

Q. 関数の引数として渡せば常に安全?
A. 多くの場合関数引数を使うと安全ですが、mutable なデフォルト引数には注意が必要です。

Q. クラス内メソッドでもこのエラーは起きる?
A. クラス内でも同様の問題が発生します。特にメソッドでインスタンス変数とローカル変数を同名で使うと混乱を招きます。


UnboundLocalError は、Python のスコープルールを正しく理解していないと頻出する典型的なエラーです。global や nonlocal キーワードを適切に使い、明確な変数設計をすることで防ぐことができます。本記事を参考に、エラーのない堅牢な Python コードを目指してください。