Python

Pythonのグローバル変数・ローカル変数について解説

By 2021年10月24日No Comments

この記事では、グローバル変数・ローカル変数について説明し、globalキーワードやnonlocalキーワードの使用方法も解説していきます。

グローバル変数・ローカル変数とは?

グローバル変数とは、全てのスコープ(変数が参照できる範囲)で使用できる変数のことです。Pythonでは、pythonファイル内の一番外側で定義された変数がグローバル変数として扱われます。

一方で、ローカル変数は一部のスコープでのみ使用できる変数のことを指します。関数の内部で定義された変数はローカル変数にあたります。

### グローバルなスコープ ###
a = "グローバル変数"

def func():

    ### ローカルなスコープ###
    b = "ローカル変数"

グローバル変数の基本

グローバル変数は、関数内部やクラス内部など、どこからでも参照することができます。

global_var = 3.14

def func():
    print("関数内部:", global_var)

class MyClass:
    def __init__(self):
        print("クラス内部", global_var)

# 出力の確認
print("ファイルの最外部:", global_var)
func()
c = MyClass()

(出力結果)

ファイルの最外部: 3.14
関数内部: 3.14
クラス内部 3.14

また、グローバル変数は「global」キーワードを使用することで、pythonファイルの一番外側に限らずどこからでも定義することができます。

def func():
    global global_var
    global_var = "グローバル変数"

func()
print(global_var)

(出力結果)

グローバル変数

グローバル変数をローカルで使用するときの注意点

グローバル変数をローカルなスコープで使用する場合、直接「参照」することはできても、「変更」することはできません。

以下のコードは、グローバル変数を関数内部からprintするだけのコードであり、問題なく動作します。

global_var = "グローバル変数"

def func():
    print(global_var) # グローバル変数を参照する

func()

(出力結果)

グローバル変数

しかし、以下のコードのように、グローバル変数の文字列を直接書き換えるようなコードはエラーとなります。

global_var = "グローバル変数"

def func():
    global_var += "(ローカル書き換え)"  # グローバル変数をローカルスコープで書き換える

func()

(出力結果)

UnboundLocalError: local variable 'global_var' referenced before assignment

(※なお、正確には変数の「変更」が問題ではなく、「代入前の参照」がエラーの原因です。+=は元の変数の参照を伴う代入操作であるため問題となります。リストオブジェクトのappend操作などは問題ありません。)

すでに定義されたグローバル変数をローカルなスコープで変更などしたい場合は、「global」キーワードで変数を宣言しておく必要があります。

global_var = "グローバル変数"

def func():
    global global_var
    global_var += "(ローカル書き換え)"  # グローバル変数をローカルスコープで書き換える

func()
print(global_var)

(出力結果)

グローバル変数(ローカル書き換え)

また、ローカルなスコープ内で、グローバル変数と同名の変数を定義した場合、それぞれの変数は別々に存在することとなります。

global_var = 1

def func():
    global_var = 2
    print("関数内部:", global_var)

print("関数呼び出し前:", global_var)
func()
print("関数呼び出し後:", global_var)

(出力結果)

関数呼び出し前: 1
関数内部: 2
関数呼び出し後: 1

上記の例のように、グローバル変数と関数内部のローカル変数はそれぞれ別の数値を表しています。

なぜこのような結果になるかは、変数のidを確認すると分かりやすいでしょう。

global_var = 1

def func():
    global_var = 2
    print("関数内部:", id(global_var))

print("関数呼び出し前:", id(global_var))
func()
print("関数呼び出し後:", id(global_var))

(出力結果)

関数呼び出し前: 4561725888
関数内部: 4561725920
関数呼び出し後: 4561725888

id()関数を使用すると、変数毎にどんな識別番号が振られているかを知ることができます。同じidを持つ変数は、PCの同じメモリ上に保存されており、値も当然同じです。

関数の外側で定義されたglobal_varと、関数内部で定義されたたglobal_varではidが異なるため、変数の名前は同じでも別々に管理されていることがわかります。

ローカル変数とnonlocalキーワード

ローカル変数は、基本的に同じスコープ内でのみで使用することができます。

def func():
    local_var = "ローカル変数"
    print(local_var)

func()

(出力結果)

ローカル変数

ローカル変数が定義されたスコープより外側のスコープでは、そのローカル変数を使用することはできません。

以下のコードは、エラーとなります。

def func():
    local_var = "ローカル変数"

print(local_var)

(出力結果)

NameError: name 'local_var' is not defined

ローカル変数を定義したスコープより内側のスコープでも、そのローカル変数を「参照」することはできます。

def outer_func():

    local_var = "ローカル変数"

    def inner_func():
        print("inner_func内部:", local_var)

    print("outer_func内部:", local_var)
    inner_func()

outer_func()

(出力結果)

outer_func内部: ローカル変数
inner_func内部: ローカル変数

グローバル変数と同様、外側のスコープにある変数は「変更」操作ができません。

以下のコードはエラーとなります。

def outer_func():

    local_var = "ローカル変数"

    def inner_func():
        local_var += "(変更操作)"
        print("inner_func内部:", local_var)

    print("outer_func内部:", local_var)
    inner_func()

outer_func()

(出力結果)

UnboundLocalError: local variable 'local_var' referenced before assignment

「nonlocal」キーワードを使用することで、「変更」などの操作が行えます。

def outer_func():

    local_var = "ローカル変数"

    def inner_func():
        nonlocal local_var
        local_var += "(変更操作)"
        print("inner_func内部:", local_var)

    print("outer_func内部:", local_var)
    inner_func()    print("outer_func内部:", local_var)

outer_func()

(出力結果)

outer_func内部: ローカル変数
inner_func内部: ローカル変数(変更操作)
outer_func内部: ローカル変数(変更操作)

また、グローバル変数と同様、スコープの外側と内側で同名の変数が定義されている場合、変数は別々に管理されます。

def outer_func():

    local_var = 1

    def inner_func():
        local_var = 2
        print("inner_func内部:", local_var)

    print("outer_func内部:", local_var)
    inner_func()
    print("outer_func内部:", local_var)

outer_func()

(出力結果)

outer_func内部: 1
inner_func内部: 2
outer_func内部: 1

Pythonの変数の処理順序

同名の変数があった場合、Pythonの変数は基本的に以下のような順序で探索されます。

1. 同じスコープ内の変数

2. 外側のスコープの変数

3. 2で変数が見つからない場合、更に外側のスコープの変数

4. グローバル変数

例として、以下のコードでは何が表示されるか考えてみてください。

x = 0

def func1():
    x = 1

    def func2():

        def func3():
            print(x)

        func3()

    func2()

func1()

答えは「1」になります。

Pythonは以下のように変数を探索し、結果を出力します。

1. func3内に変数xは存在しないので、外側のスコープを探索する

2. func2内に変数xは存在しないので、更に外側のスコープを探索する

3. func1内に変数x=1が定義されているので、最終的に「1」を表示する

グローバル変数とモジュール

pythonでは、グローバル変数は同じpythonファイル内であればどこからでも参照できるのに対し、別ファイルのグローバル変数を参照することはできません。

なお、1つのpythonファイルのことをモジュールと呼びます。言い換えれば、同一モジュール内でのみグローバル変数が参照できることになります。

C言語のように、1つのファイル内で定義した変数が全てのファイルから参照することのできるような言語もあるため、pythonのグローバル変数は「モジュールのグローバル変数」、のように呼んだ方がやや正確です。本記事では簡易的な説明のため、単にグローバル変数と呼んでいます。

[ file1.py ]
file1_var = "file1の変数"
[ file2.py ]
print(file1_var)

上記のようなコードは実行できません。他モジュールのグローバル変数を使用したい場合は以下のように書きます。

[ file1.py ]
file1_var = "file1の変数"
[ file2.py ]
from file1 import file1_var

print(file1_var)

(実行結果)

file1の変数

まとめ

・グローバル変数とは、全てのスコープで使用できる変数のことであり、pythonファイル内の一番外側で定義された変数がグローバル変数として扱われる。また、「global」キーワードを用いることで、どこでもグローバル変数を定義できる。

・ローカル変数は関数の内部などの一部のスコープでのみ使用できる変数のことを指す。スコープの外側から、スコープの内側で定義されたローカル変数は参照できないが、内側から外側の変数に参照することはできる。

・自身より外側のスコープの変数について、「変更操作(参照を伴う代入)」をする場合、グローバル変数なら「global」キーワード、ローカル変数なら「nonlocal」キーワードで宣言する必要がある。

Udemyの動画学習でもPythonを勉強しよう!

「平日の夜の勉強会には時間が間に合わなくて参加できない」「通勤時間のわずかな隙間時間を勉強時間にあてたい」「本ではよく分からないところを動画で理解を深めたい」そんなあなたはUdemyの動画学習がお勧めです!

UdemyのPythonおすすめ33講座レビューリスト
HOSL

Author HOSL

More posts by HOSL