エラーの概要
Pythonにおいて、UnboundLocalErrorは関数内で変数が適切に初期化されていない場合に発生する例外です。このエラーは、ローカルスコープ内で宣言された変数が参照される前に値が割り当てられていないことを示します。
主な発生パターン
- 事前参照: 変数への代入より前にその変数を使用するとエラーになります。
- 名前の衝突: 関数内でグローバル変数と同じ名前のローカル変数を定義し、かつ代入前に参照した場合に発生します。
- クロージャーの問題: 内部関数から外部関数の変数を参照する際、適切なキーワードを使用しないとエラーとなります。
解決策
基本的な対応方法
- 変数は必ず使用前に初期化を行う。
- グローバル変数と同一名のローカル変数を使用する場合は
globalキーワードを利用する。 - クロージャーで外部スコープの変数を変更する際は
nonlocalキーワードを使用する。
コード例
以下の例では、変数xが関数内で宣言される前に参照されているためエラーが発生します:
def faulty_function():
print(x)
x = 10
# faulty_function() # 実行すると UnboundLocalError が発生
これを修正するには、変数の代入を先に行います:
def corrected_function():
x = 10
print(x)
corrected_function() # 正常に動作
グローバル変数との競合
次のようなケースでも同様のエラーが発生します:
y = 5
def conflicting_scope():
print(y)
y = 20
# conflicting_scope() # UnboundLocalError 発生
これは、関数内でyがローカル変数として扱われるため、代入前の参照でエラーとなります。対処法は以下の通りです:
z = 5
def resolved_scope():
global z
print(z)
z = 20
resolved_scope()
print(z) # 出力: 20
クロージャーにおけるnonlocalの使用
内部関数から外部関数の変数を更新する場合、nonlocalが必要です:
def outer():
counter = 0
def inner():
nonlocal counter
counter += 1
return counter
return inner
increment = outer()
print(increment()) # 1
print(increment()) # 2
予防策
- 関数内のすべての変数が明確に初期化されているか確認する。
- 静的解析ツールやIDEの警告機能を活用する。
- ユニットテストを通じて境界条件を検証する。
- 意味のある変数名を使用し、グローバル変数の濫用を避ける。