まずはおさらい
とりあえず表示してみる
global_variable = "This is a global."
def func():
print(global_variable)
func() # This is a globalと表示される
関数内で値を操作するなら、globalを使う。
global_variable = "This is a global."
def func():
global global_variable # これ重要
global_variable = "Change the value"
print(global_variable)
func() # Change the valueと表示される
print(global_variable) # Change the valueと表示される
UnboundLocalErrorになるパターン
global_variable = 0
def func_error():
global_variable += 1
func_error() # UnboundLocalError: local variable 'global_variable' referenced before assignment
これはglobal_variableがローカル変数として宣言される前に、いきなり加算しようとしているのだ。だからPythonさんからしたら、「誰だ君は」となるのである。これは上記のようにglobal宣言しておくと回避できる。
よく分からんがエラーになるパターン
以下のパターンもダメ。
global_variable = 0
def func_error():
print(global_variable)
global_variable = 1
func_error() # UnboundLocalError: local variable 'global_variable' referenced before assignment
面白いのがエラーが出ている個所がprint(global_variable)なのだ。Pythonさんはどうやら、global_variableをローカル変数とみなしたようだ。しかし、print(global_variable)を読みだした時はまだ宣言されてないので、先に「宣言してちょうだい」と促しているのだ。
あれ?ちょっとまった。
ここで一つ疑問が出てくる。以下の場合はどんなエラーになるのか。(ご指摘を受けたので修正しました。)
def func_error_local():
print(hogehoge)
hogehoge= 1
func_error_local() # UnboundLocalError: local variable 'global_variable' referenced beford
これも同様に、UnboundLocalErrorになった。
正直分かりにくい
これらの挙動は個人的には違和感を感じている。globalという概念を導入した結果なのだろうか。そもそも、関数内ではglobal宣言をしないと一切アクセスできないようにすればよかったのでは?と正直思う。もしくはその逆で、完全フリーにグローバル変数へアクセスできるようにするとか。あとは、エラーの内容を「global宣言してちょうだい」にするとか。 そもそも変数が宣言されてないと、UnboundLocalErrorが出るようだが、やっぱりエラーが分かりにくい。
この挙動が意図したものか、それとも歴史がそうさせたのか、もしくは海より深い理由があるのか。正直よく分からんので知っている人がいたら教えて欲しいです。
でわでわ。