33.global変数とスコープ

関数などを使う際に必ず付いてくるのが、スコープという概念です。
これは宣言した変数が使える範囲を示す概念のことです。

スコープには
グローバルとローカルの2種類があります。

ざっくり説明すると、一番外にあるものがグローバル
関数のブロックの中がローカルということになります。

ではその違いについて見て見ましょう。
まずはグローバルで使える変数を用意します。

In [1]:
global_var = 'global'

次に関数を定義して、その中で使える変数を用意します。

In [2]:
def local_def():
    # ローカル用の変数
    local_var = 'local'
    return local_var

グローバルの変数の呼び出しは

In [3]:
print(global_var)
global

ローカル変数の呼び出しは

In [4]:
print(local_var)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-4-38c61bb47a8e> in <module>()
----> 1 print(local_var)

NameError: name 'local_var' is not defined

変数が定義されていないと、エラーが出てしまいます。

ローカルで定義したものは、
そのローカルのブロックの中でしか使えないからです。

なのでこのlocal変数が使えるのは、
定義した関数の中だけになります。

次に関数をいじって、グローバル変数を関数の中で読んでみましょう。

In [5]:
def local_def():
    # グローバル変数の参照
    print(global_var)

local_def()
global

グローバルで宣言した変数はどこでも使用することができます。

ローカルで宣言したものを
グローバルで使うにはどうすればいいでしょうか?

関数であれば戻り値として
グローバルの方に戻すことで使い回すことができます。

In [6]:
def local_def():
    local_var = 'local'
    # ローカルで定義した変数を戻す
    return local_var

g2 = local_def()
print(g2)
local

for文の方も見て見ましょう。

In [7]:
global_var = 'g'

for i in range(5):
    j = global_var*i
    
# ローカルの変数をそのままプリントする
print(i,j)
4 gggg

結果は最終的に代入された結果のみが反映されることになります。

for文のブロックで使用していた変数などを
気づかずに再利用してしまうケースなどがありえると思いますが、
変数に格納した値によってはプログラムの結果に大きく影響が出てきます。

最後に、グローバルとローカルで変数名がかぶってしまった場合どうなるか

In [8]:
sp = 'global'

def local_def():
    sp = 'local'
    print(sp)

local_def()
print(sp)
local
global

一旦ローカルで同じ変数名で定義していますが
関数を呼び出した際はその関数で定義した変数名で
上書きされる形になるのでローカルで代入した値が表示されます。

その後グローバルの変数を呼び出す際には
元の代入された値が表示されるという仕組みです。

global という予約語を用いると、
このグローバルの変数をローカル側で操作することできます。

In [9]:
sp = 'global'

def local_def():
    # ローカルでグローバル変数として定義
    global sp 
    sp= 'local'
    print(sp)

local_def()
print(sp)
local
local

一旦ローカルで変数の前にglobalをつけて宣言し、
その後に変数に代入するとグローバルの変数の操作をすることができます。

グローバルと、ローカルで同じ変数を用いると、
不慮のバグの元になりやすいです。

なので慣れないうちは変数名はなるべく被らないような
名称にすることをお勧めします。