Python

【Python】名前空間とスコープについて

この記事では、Pythonの名前空間とスコープについて解説します。

名前空間(namespace)とは

名前空間とは、変数が所属している領域のことを言います。名前空間は、名前とオブジェクトが対応付けられた辞書として管理されています。

名前空間の種類

名前空間には、以下のような種類があります。

組み込み名の集合(組み込み関数や組み込み例外名など):

組み込み名の集合の名前空間は、インタプリタが起動する時に作成され、インタプリタが終了するまでずっと保持されます。

モジュール内のグローバルな名前:

モジュールのグローバルな名前空間は、モジュール定義が読み込まれたときに作成され、インタプリタが終了するまで残ります。

関数を呼び出したときのローカルな名前:

関数のローカルな名前空間は、関数が呼び出されたときに作成され、関数から戻ったときや、関数内で例外が送出され、かつ関数内で処理されなかった場合に削除されます。

名前空間の確認

グローバルな名前空間を globals()関数、ローカルな名前空間を locals()関数で確認することができます。

def func():
    l = 'ローカル変数'
    print(f'locals: {locals()}')


g = 'グローバル変数'
print(f'globals: {globals()}')
>> globals: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7facabdb8d90>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/Python/main.py', '__cached__': None, 'func': <function func at 0x7facabdbaf70>, 'g': 'グローバル変数'}

func()
>> locals: {'l': 'ローカル変数'}

スコープ(scope)とは

スコープとは、直接アクセスできる名前空間の範囲のことを言います。直接アクセスできるということは、「obj.x」ではなく「x」でアクセスできるということです。

スコープの種類と優先順位

スコープには、以下のような種類があります。以下の順に検索されます。

1: ローカルスコープ

自らの関数のブロック内。

2: エンクロージングスコープ

関数がネストされている場合の外側の関数のブロック内。よりローカルに近い方から検索される。

3: グローバルスコープ

自らのモジュール内。

4: ビルドインスコープ

どこからでも参照できる。組み込み関数や組み込み定数など。

以下は、inner_func関数のブロック内から見たスコープです。

# グローバルスコープ
g = 'グローバル'

def outer_func():
    # エンクロージングスコープ
    e = 'エンクロージング'

    def inner_func():
        # ローカルスコープ
        l = 'ローカル'

変数の再束縛

ローカルスコープ内からグローバルやエンクロージングで宣言された変数は参照することができますが、そのままでは代入することができません。

そんな時は、global文、またはnonlocal文を使います。

# グローバルスコープ
g = 'グローバル'

def outer_func():
    # エンクロージングスコープ
    e = 'エンクロージング'

    def inner_func():

        # グローバル変数を再束縛
        global g

        # グローバルを除く1つ外側のスコープの変数を再束縛
        nonlocal e

        # 再束縛したので代入可能
        g = '書き換えたグローバル'
        e = '書き換えたエンクロージング'

        print(g, e)

    inner_func()


outer_func()
>> 書き換えたグローバル 書き換えたエンクロージング

要するに、global文はグローバル変数を、nonlocal文はグローバル以外の1つ外側のスコープの変数を使うことを明示的に宣言できるってことです。

代入する以外にも、同名の変数が存在する場合にも使うことができます。

最短3か月でエンジニア転職『DMM WEBCAMP COMMIT』