Python ネームスペースと変数スコープ: 名前、バインディング、スコープを理解する
Python ネームスペースと変数スコープ
Pythonにおける名前、ネームスペース、変数スコープの仕組みを、明確な例とベストプラクティスで解説します。
Pythonにおける「名前」とは?
「The Zen of Python」(import this)の最後の行は「Namespaces are one honking great idea -- let's do more of those!」です。ではネームスペースとは?まず「名前」を定義しましょう。
名前、または識別子は、オブジェクトを参照するラベルです。Pythonではすべてがオブジェクトであり、名前はそれにアクセスする便利な方法を提供します。
例えばa = 2を実行すると、整数2がメモリに格納され、aがその参照になります。組み込みid()関数はオブジェクトのメモリアドレスを返します。
# 注意: id値は環境により異なります
a = 2
print('id(2) =', id(2))
print('id(a) =', id(a))
出力
id(2) = 9302208 id(a) = 9302208
両名が同じオブジェクトを指すため、id()値が一致。aを再バインドするとどうなるか:
# 注意: id値は環境により異なります
a = 2
print('id(a) =', id(a))
a = a + 1
print('id(a) =', id(a))
print('id(3) =', id(3))
b = 2
print('id(b) =', id(b))
print('id(2) =', id(2))
出力
id(a) = 9302208 id(a) = 9302240 id(3) = 9302240 id(b) = 9302208 id(2) = 9302208
a = a + 1実行時、新しいオブジェクト3が作られ、aがそれを参照。id(a)とid(3)が同一に。続くb = 2は既存の2オブジェクトにbをバインドし、重複格納を回避。

この動的な名前バインディングがPythonの柔軟性を生みます:単一の識別子が関数を含むあらゆる型の値を指せます。
def printHello():
print("Hello")
a = printHello
a()
出力
Hello
識別子aが関数printHelloを参照し、直接呼び出せます。
ネームスペースとは?
ネームスペースは名前からオブジェクトへのマッピング。定義したすべての識別子と関連オブジェクトを保持する辞書と考えられます。
Pythonは複数のネームスペースを同時にサポートし、それぞれ互いに隔離されています。インタプリタはセッションの存続期間中持続する組み込み名を含むグローバルネームスペースを作成。各モジュールは独自のグローバルネームスペースを持ち、各関数やクラス定義は新しいローカルネームスペースを導入します。

Pythonの変数スコープ
ネームスペースが存在する一方、スコープは名前が修飾なしでアクセスできる場所を決定します。
任意の時点で、プログラムには少なくとも3つのネストしたスコープがあります:
- 現在実行中の関数のローカルスコープ。
- モジュールのグローバルスコープ。
- 常に利用可能な組み込みスコープ。
関数内で名前を参照すると、Pythonはローカルネームスペース→グローバル→組み込みの順で検索。関数内にさらに関数がある場合、内側の関数が新しいネストスコープを導入します。
例: スコープとネームスペースの相互作用
以下のコードを考えます:
def outer_function():
b = 20
def inner_func():
c = 30
a = 10
ここではaはモジュールのグローバルネームスペースに存在。bはouter_functionのローカル、cはネストしたinner_funcのローカルネームスペースに属します。
inner_func内では、cはローカル、bは非ローカル、aはグローバル。cは読み書き可能だが、bとaはglobalやnonlocalで明示宣言しない限り読み取りのみ。
より具体的な例:
def outer_function():
a = 20
def inner_function():
a = 30
print('a =', a)
inner_function()
print('a =', a)
a = 10
outer_function()
print('a =', a)
出力は3つの異なるaバインディングを示します:
a = 30 a = 20 a = 10
すべての代入をグローバルaに強制するにはglobalキーワードを使用:
def outer_function():
global a
a = 20
def inner_function():
global a
a = 30
print('a =', a)
inner_function()
print('a =', a)
a = 10
outer_function()
print('a =', a)
出力は単一のグローバルaを反映:
a = 30 a = 30 a = 30
これらの例は、Pythonのネームスペースとスコープルールが変数の可視性と変更をどう制御するかを示しています。
Python
- Python キーワードと識別子: 予約語と命名規則をマスター
- Python 文・インデント・コメント: 明確なガイド
- Python 変数・定数・リテラル: 包括的ガイド
- Python 型変換とキャスト: 包括的ガイド
- Python I/Oとモジュールインポート完全マスター: 実践ガイド
- Python 演算子完全マスター: 包括的ガイド
- Python グローバル・ローカル・非ローカル変数を理解する
- Pythonにおける数値、型変換、数学のマスター
- Pythonディレクトリ・ファイル操作マスター:作成、移動、一覧、リネーム、削除
- Pythonエラーと組み込み例外をマスターする
- Pythonで現在の日付と時刻を取得する実践ガイド