Help us understand the problem. What is going on with this article?

UnboundLocalErrorについて考察してみた

まずはおさらい

とりあえず表示してみる

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が出るようだが、やっぱりエラーが分かりにくい。

この挙動が意図したものか、それとも歴史がそうさせたのか、もしくは海より深い理由があるのか。正直よく分からんので知っている人がいたら教えて欲しいです。

でわでわ。

Boccochan
ソフトウェアの開発やってます。最近はDevOpsに取り組んでます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした