名前空間とスコープ
名前空間とスコープ ▲
名前空間とは、変数名や関数名などの名前とオブジェクトを対応付けることである
名前空間に対応付けられている名前を直接参照できる範囲のことをスコープという
例えば関数の中で定義された変数は、関数の外から直接参照することはできない
Pythonのスコープには大きく分けて3種類あり、ビルトインスコープ、グローバルスコープ、ローカルスコープと呼ばれる
PythonではC#などの言語ほど細かくスコープを生成しないため、例えばif文やfor文などではスコープは生成されないことに注意する
ビルトインスコープ ▲
ビルトインスコープは一番外側のスコープであり、組み込み定数や組み込み関数などが含まれる
例えば True False や、None などの組み込み定数や、print関数やmax関数などの組み込み関数はプログラムのどの領域でも使用することができる
グローバルスコープ ▲
グローバルスコープはビルトインスコープの内側のスコープで、1つのモジュール全体を含む
グローバルスコープはモジュールスコープとも言い、そのモジュール内のどこからでも参照できることを指す
例えば関数やクラスの外で定義された変数はその Python ファイル内のどこからでも参照できる
現在のモジュールで有効な名前空間は globals() を呼び出すことで確認できる
ローカルスコープ ▲
ローカルスコープはグローバルスコープのさらに内側のスコープで、関数やクラスの中の領域を指す
ローカルスコープの名前には、同一のローカルスコープの中からしか参照できない
現在のローカルスコープ内で有効な名前空間は locals() を呼び出すことで確認できる
global文 ▲
ローカルスコープ内で宣言した変数をグローバルスコープのものとして扱いたいときは global文 を使用する
global文 の書き方を以下に記載する
def test_func1():
global animal
animal = 'cat'
def test_func2():
global animal
animal = 'dog'
def test_func3():
animal = 'rabbit'
def print_func():
# animal をローカルで定義していない場合はグローバルスコープを見に行く
print(animal)
# cat に書き換え
test_func1()
print_func() # cat
# dog に書き換え
test_func2()
print_func() # dog
# ローカルスコープでの書き換えなので反映されない
test_func3()
print_func() # dog
"""
上の例のように、グローバルスコープに animal が定義されていなくても使えるが、
基本的にはグローバルスコープで animal を宣言しておいて、
ローカルスコープでグローバルスコープの変数を参照したいときにglobal文を使用する
"""
### エラーケース
name = 'Tarou' # グローバルスコープとして宣言
def test_func4():
# name が以降の行でローカルスコープとして宣言されているため、この段階では未定義だとエラーが出る
print(name) # UnboundLocalError: local variable 'name' referenced before assignment
name = 'Hanako' # ローカルスコープとして宣言
print('after', name)
test_func4()
nonlocal文 ▲
ローカルスコープ内で宣言した変数を、さらに内側のローカルスコープ(関数内関数など)で扱いたいときに nonlocal文 を使用する
nonlocal文 の書き方を以下に記載する
name = 'Tarou' # グローバルスコープで name を定義
def test_func():
name = 'Hanako' # ローカルスコープで name を定義
def inner_func():
nonlocal name # 1つ外側のローカルスコープの name を使用すると宣言
name = 'Jirou'
print(name) # Jirou
inner_func()
print(name) # Jirou
test_func()
print(name) # Tarou
"""
1つ外側のローカルスコープを使用するだけなので、
グローバルスコープにまで影響していないことに注意する
なお、1つ外側のスコープがグローバルスコープの場合は、
nonlocal文を使用すると以下のエラーがでるので注意
SyntaxError: no binding for nonlocal 'name' found
"""
目次