Categories: Python

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

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

名前空間とスコープのことを知っておくことで定義した関数やクラスがどこまでの範囲でどのように呼び出せるか知ることができます。

それでは、名前空間とスコープについて見ていきましょう!

名前空間(namespace)とは?

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

名前空間の種類

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

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

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

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

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

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

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

名前空間の確認

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

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


g = 'グローバル変数'
print(f'globals: {globals()}')

func()

実行結果

globals: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': '/Users/yumaru/Desktop/Python/main.py', '__cached__': None, 'func': , 'g': 'グローバル変数'}
locals: {'l': 'ローカル変数'}

スコープ(scope)とは?

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

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

スコープには、以下のような種類があって「1」から順番に検索されます。

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つ外側のスコープの変数を使うことを明示的に宣言できるってことです。

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

ゆうまる

独学でプログラミングを勉強しているおじさん。いろんな言語を勉強したが浅く広くなためあまり仕事につながらない。また忘れっぽいため自分のブログを備忘録としても使っている。産まれてこのかたずっとネコを飼ってる生粋のネコ派。最近お腹が出てきて筋トレに奮闘中!

View Comments

Recent Posts

【Dart】コンストラクタのデフォルト引数について

Dartのコンストラクタのデフォルト引数…

2週間 ago

【Unity】有料アセットを無料で手に入れる方法

この記事では、Unityの有料アセットを…

4か月 ago

【Python】任意の秒数だけ処理を一時停止する方法【sleep()関数】

この記事では、Pythonで任意の秒数だ…

1年 ago

【Python】Wordの文書の新規作成と読み書き

この記事では、Pythonを使ってWor…

1年 ago

【Python】メタクラスって結局なんなの?

この記事では、Pythonのメタクラスに…

1年 ago