Code Fix

中級

UnboundLocalError: cannot access local variable の原因と直し方

関数内で変数に代入すると、Pythonはその変数を自動的にローカル変数とみなします。代入より前に参照すると発生します。

エラーメッセージの読み方

Traceback (most recent call last):
main.py
ファイル名
5
行番号 — 実際にクラッシュした行
increment
発生場所 — <module> ならトップレベル、関数名ならその関数の中
UnboundLocalError
例外クラス — 何が起きたか。ここを検索するのが最短です
cannot access local variable 'count' where it is not associated with a value
詳細メッセージ — どの値が問題だったか

このエラーが出る典型パターン

パターン1

 1  count = 0
 2  
 3  def increment():
 4                    
               ^
 5      count = count + 1
 6      return count
 7  
 8  print(increment())
Traceback (most recent call last): File "main.py", line 8, in <module> print(increment()) ^^^^^^^^^^^ File "main.py", line 5, in increment count = count + 1 ^^^^^ UnboundLocalError: cannot access local variable 'count' where it is not associated with a value

関数内で変数に代入すると、Pythonはその変数を自動的にローカル変数とみなします。グローバル変数を書き換えたい場合はglobal宣言が必要です。

直し方: (空)global count にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  total = 100
 2  
 3  def add_tax():
 4                    
               ^
 5      total = total * 1.1
 6      return total
 7  
 8  print(add_tax())
Traceback (most recent call last): File "main.py", line 8, in <module> print(add_tax()) ^^^^^^^^^ File "main.py", line 5, in add_tax total = total * 1.1 ^^^^^ UnboundLocalError: cannot access local variable 'total' where it is not associated with a value

代入している行が後にあっても、Pythonは関数全体を先読みしてtotalをローカル変数と判断します。読み込む行が先に実行されるため、その時点でまだ値がありません。

直し方: (空)global total にします。

この問題を解いてみる →

パターン3

 1  flag = False
 2  
 3  def toggle():
 4                   
              ^
 5      flag = not flag
 6      return flag
 7  
 8  print(toggle())
Traceback (most recent call last): File "main.py", line 8, in <module> print(toggle()) ^^^^^^^^ File "main.py", line 5, in toggle flag = not flag ^^^^ UnboundLocalError: cannot access local variable 'flag' where it is not associated with a value

真偽値の反転のような単純な処理でも同じです。関数の外の変数を書き換えるにはglobal宣言が必要です。

直し方: (空)global flag にします。

この問題を解いてみる →

よくある誤解

関数の外で同名の変数が定義されていても、関数内で一度でも代入している変数はローカル扱いになります。読み込む前に代入されているかどうかは関係なく、関数全体を見て判断されます。

まとめ

UnboundLocalError: cannot access local variableは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)