
Table of Contents(目次)
1. スコープとは何か?:Python変数の可視範囲を理解する
スコープ(scope)とは、変数が「どこから見えるか」「どこで使えるか」を決めるルールのことです。Pythonでは、変数が定義された場所によって、参照できる範囲が変わります。
スコープを理解すると、意図しないエラーを防ぎ、きれいで安全なコードを書けるようになります。
x = 10 # グローバルスコープ(どこからでもアクセス可能)
def sample():
y = 5 # ローカルスコープ(関数の中だけで有効)
print(x) # OK
print(y) # OK
sample()
print(x) # OK
print(y) # エラー(yは関数の外から見えない)
上の例では、xは「グローバル変数」であり、どこからでも参照できます。一方で、yは「関数内のローカル変数」で、関数の外では見えません。
2. スコープの4階層(LEGBルール)と探索順序
Pythonには、スコープの探索ルールが決まっています。これを「LEGBルール」と呼びます。
LEGBルール:
- L (Local):関数内などのローカルスコープ
- E (Enclosing):入れ子関数の外側関数のスコープ
- G (Global):モジュール全体で有効なスコープ
- B (Built-in):Python組み込みのスコープ(len, printなど)
x = 'global'
def outer():
x = 'enclosing'
def inner():
x = 'local'
print(f'07行目のx = {x}') # local
inner()
print(f'09行目のx = {x}') # enclosing
outer()
print(f'12行目のx = {x}') # global
07行目のx = local
09行目のx = enclosing
12行目のx = global
Pythonは、変数を探すときにこの順番(L → E → G → B)で探していきます。
3. グローバル変数とローカル変数の違い
グローバル変数は、モジュール全体で使える変数です。一方、ローカル変数は関数の中だけで使える変数です。
count = 0 # グローバル変数
def add():
count = 10 # ローカル変数(別物)
print('関数内:', count)
add()
print('関数外:', count)
関数内: 10
関数外: 0
この場合、関数内で定義されたcountは、グローバル変数countとは別物です。関数外の値は変わりません。
関数の中にcount = 10のような変数を定義する行が存在すると、Pythonは関数の中に出てくるcountをローカル変数として扱い、グローバル変数のcountは参照できなくなります。ですので、ローカル変数countの初期化が行われる前にcountの値を参照しようとするとエラーになります。
count = 0 # グローバル変数
def add():
print('関数内:', count) # ローカル変数が定義する前に参照しようとするとエラーになる
count = 10 # ローカル変数(別物)
add()
UnboundLocalError: cannot access local variable 'count' where it is not associated with a value
(UnboundLocalError: 値に関連付けられていない場所でローカル変数 『count』 にアクセスできません)
最初の例のように、グローバル変数と同じ名前の関数内の変数に対して、値を代入するなどの編集を行わなければ、グローバル変数の値を参照することはできます。
x = 10 # グローバル
def sample():
print(x) # 変数xに対して関数の中で編集を行う処理を行わなければ、参照することは可能
sample()
4. global文でグローバル変数を更新する方法
関数の中からグローバル変数を変更したい場合は、global文を使います。
count = 0
def add():
global count
count += 1
print('関数内:', count)
add()
print('関数外:', count)
関数内: 1
関数外: 1
global countと宣言することで、関数内でもグローバル変数countを操作・参照できるようになります。
5. nonlocal文と入れ子関数による変数操作
入れ子関数(関数の中に関数がある構造)では、外側の関数の変数をnonlocalで操作できます。
def outer():
x = 0
def inner():
nonlocal x
x += 1
print('inner:', x)
inner()
print('outer:', x)
outer()
inner: 1
outer: 1
ここでnonlocal xを使うことで、inner()の中からouter()の変数xを更新できます。
6. スコープと変数のライフタイム(生存期間)
スコープと「変数の生存期間(ライフタイム)」は密接に関係しています。ローカル変数は関数が実行されるたびに作られ、終了時に破棄されます。
def counter():
x = 0
x += 1
print(x)
counter()
counter()
1
1
この例では、毎回xがリセットされます。関数をまたいで値を保持したい場合は、次のような構成を考える必要があります。
- グローバル変数を使う
- クラス・クロージャなどの仕組みを利用する
- 返り値と引数を使って、値を受け渡す
7. スコープを意識したクリーンな関数設計の実践例
スコープを意識すると、グローバル変数に依存しない「クリーンなコード」を設計できます。次の例では、グローバル変数を使わずに状態を保持する方法を紹介します。
def create_counter():
count = 0
def add():
nonlocal count
count += 1
return count
return add
counter = create_counter()
print(counter()) # 1
print(counter()) # 2
print(counter()) # 3
このようにnonlocalとクロージャを使えば、グローバル変数に頼らずに状態を管理できます。スコープを理解することで、保守性の高い関数設計が可能になります。
クロージャーについては専用のレクチャーで学習します。






