グローバル変数
関数やクラス定義の外側の領域のことをグローバルスコープといい、ここで作られた変数のことをグローバル変数という。グローバル変数はそのファイル内の全ての範囲で利用することができるが、Pythonのそれは扱いに若干の注意を要する。 グローバル変数の参照
関数内(ローカルスコープ)においてグローバル変数の値を参照することができる。これは意図した通りに動作する。
code:global_val1.py
def func():
print('ローカルスコープ:', x) # 関数内からグローバル変数xを参照
x = 5 # xはグローバル変数
print('グローバルスコープ:', x)
func()
結果は次のようになり、関数内からグローバル変数が見えていることが確認できる。
code:結果.sh
グローバルスコープ: 5
ローカルスコープ: 5
~~~~~~~~~~~~~~~~~~
グローバル変数に代入したつもりが...
ローカルスコープにおけるグローバル変数への代入処理は注意が必要である。もし、 あるローカルスコープ内にグローバル変数への代入文が存在すると、それはローカル変数として扱われる。
C言語とは異なる動作のようだ。例を見ていこう。
(1)において、関数func内でグローバル変数に値を代入しているように見える。
code:global_val2.py
def func():
x = -5 # (1):ローカル変数が作られる
print('ローカルスコープ:', x) # (2):ローカル変数
x = 5 # グローバル変数
print('グローバルスコープ:', x)
func()
print('グローバルスコープ:', x)
しかしながら、(1)の代入文の結果新たなローカル変数xが生成され、それに代入が行われる。つまり、グローバル変数xに対しての操作は行っていない。
code:(結果).sh
グローバルスコープ: 5
ローカルスコープ: -5
グローバルスコープ: 5
これはつまり、関数funcのローカルスコープにおいて、グローバル変数xはローカル変数xにより覆い隠されていることを意味する。これはシャドウイングとよばれるプログラミング技法です。(参考:シャドゥイング【C言語】) 補足
「代入文が存在すると、そのスコープ内ではローカル変数として扱われる」ことを体感するために、上のプログラムの一部を修正する。
code:global_val3.py
def func():
print('ローカルスコープ:', x) # (1):xはローカル変数
x = -5 # (2):xはローカル変数として認識
x = 5 # グローバル変数
print('グローバルスコープ:', x)
func()
print('グローバルスコープ:', x)
関数func内では、(2) の代入文があるため変数xはローカル変数として認識される。しかしながら、(1) の時点では変数xに対する代入処理が行われておらず、従って変数xは作られていない。
UnboundLocalError: local variable 'x' referenced before assignment
「変数xには何も割り当てられていない」エラーが生じる。
global宣言
https://scrapbox.io/files/65068c2117899c001b5dcba1.png