グローバル変数とローカル変数

入門Python3 4.10


プログラムのメイン部分に書いた変数はグローバル変数となり、defなど関数内に書いた変数はローカル変数になる。

グローバル変数は関数内から参照は出来るが変更はできない。

val = 100 # グローバル変数

def foo ():
    print(val) # グローバル変数の参照はOK
    val = 200  # グローバル変数の変更はエラー

foo()
$ py main.py
Traceback (most recent call last):
  File "main.py", line 9, in <module>
    foo()
  File "main.py", line 6, in foo
    print(val) # グローバル変数の参照
UnboundLocalError: local variable 'val' referenced before assignment


もしグローバル変数を関数内でも変更したい場合はglobal文を使う。

val = 100

def foo ():
    global val # global宣言
    print(val)
    val = 200 # 変更してもエラーにならない
    print(val)

foo()
$ py main.py
100
200


次にローカル変数ですが、関数内で定義したものがローカル変数になります。

def foo ():
    val = 10 # ローカル変数
    print(val)

foo()
$ py main.py
10


そしてここからが少しややこしいのですが、以下のように書いてもエラーにならず動きます。

val = 100 # グローバル変数

def foo ():
    val = 10 # ローカル変数
    print(val)

foo()
$ py main.py
10

一見valというグローバル変数に10を代入しているようにも見えるのですがこれはローカル変数を定義していることになるようです。

関数内でvalを先に参照してしまうとそれはグローバル変数となり、以後グローバル変数として扱われるようですが、先にvalに代入をするとそれはローカル変数になるという仕様みたいです。

ちょっとわかりにくいですねぇ、初めから関数内ではglobal文を使わない限りグローバル変数の参照も変更もできない仕様にしておけばいいのにと思いますが・・・。


ちなみにglobalsやlocalsという関数を使えば定義されている変数が辞書形式で取得することができます。

val = 100
def foo ():
    val = 10
    print(locals()) # ローカル変数の表示

foo()
print(globals()) # グローバル変数の表示
$ py main.py
{'val': 10}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000000272A160>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'main.py', '__cached__': None, 'val': 100, 'foo': <function foo at 0x00000000020A3E18>}


グローバル変数の方にはよくわからないものがたくさん定義されてますね。