Pythonのスコープとは?ローカル変数・グローバル変数の違いと使い分け
生徒
「Pythonで変数が関数の中と外で違って見えるんですが、どういう意味ですか?」
先生
「それはスコープという範囲による違いなんです。関数の内側だけで使えるローカル変数と、どこでも使えるグローバル変数がありますよ。」
生徒
「ローカル変数とグローバル変数の違いと、それぞれどう使い分ければいいのか教えてください!」
先生
「もちろんです!Pythonのスコープと変数の使い方を分かりやすく説明しますね。」
1. Pythonのスコープとは?変数の「有効範囲」を理解する
Pythonにおける「スコープ(Scope)」とは、作成した変数や関数が「プログラムのどこから参照できるか」という有効範囲を決めるルールのことです。すべての変数には「寿命」と「活動限界」があると考えてください。
例えば、自分の部屋(関数の中)にあるスマホは自分だけが使えますが、公園(関数の外)にある時計は誰でも見ることができますよね。このように、Pythonでも「どこで定義したか」によって、使える場所が厳密に区別されています。
Pythonのスコープには、大きく分けて以下の2つの基本ルールがあります。初心者のうちは、まずこの2つをしっかり押さえましょう。
- ローカル変数(Local Scope):特定の関数の中で定義され、その関数の実行中だけ有効な「使い捨て」の変数です。
- グローバル変数(Global Scope):プログラムの一番外側で定義され、どこからでもアクセスできる「共有」の変数です。
なぜこの区別が必要なのでしょうか? もしすべての変数がどこからでも書き換えられてしまうと、プログラムが大きくなった時に「どのコードが原因でデータが変わったのか」が分からなくなり、重大なバグ(ミス)に繋がるからです。スコープを意識することは、安全で読みやすいコードを書くための第一歩となります。
2. ローカル変数とは?
ローカル変数は関数の中でdefやforの中で作られ、その中だけで生きている「一時的な変数」です。関数の外からは見えません。
def greet():
message = "こんにちは" # ローカル変数
print(message)
greet()
print(message) # エラーになります
こんにちは
NameError: name 'message' is not defined
この例ではmessageは関数内のローカル変数なので、関数外で使おうとするとエラーになります。
3. グローバル変数とは?
グローバル変数は関数の外に作る変数で、スクリプト全体や他の関数でも使えます。広い範囲で共有できる変数です。
name = "たろう" # グローバル変数
def say_name():
print("あなたの名前は", name)
say_name()
print(name)
あなたの名前は たろう
たろう
このように、関数の中でも外でも同じnameが使えます。
4. globalキーワードでグローバル変数を書き換える
関数の中でグローバル変数を書き換えたい場合、global(グローバル)キーワードを使います。これを使わないと、新しくローカル変数が作られてしまいます。
counter = 0 # グローバル変数
def increment():
global counter
counter = counter + 1 # グローバル変数を書き換え
increment()
print(counter) # 1
1
global counterがないと、関数内でcounterを変更しても反映されません。
5. なぜローカル変数を使うの?安全でエラーを防ぐ
ローカル変数は関数の中だけにあるので、別の場所で影響したり、意図しない書き換えが少なくなり、安全です。例えるなら、自分のノートにだけメモを書くイメージです。
6. なぜグローバル変数は注意が必要?保守性と依存性
グローバル変数はどこでも使える代わりに、プログラムが大きくなると「どこで使われているか」が分かりにくくなり、バグの原因になります。例えると、みんなが使う共有ノートに勝手に書き込むようなものです。
7. おすすめの使い分けパターン
実務や開発では、基本的にローカル変数を使い、必要最低限だけグローバル変数を使うのが良いです。
- 関数の中で完結する処理はローカル変数だけで書く
- 設定値や定数(MAX値など)だけグローバルに置いて読み込む
- どうしても関数間で変更が必要な変数があれば、
globalで書き換える
8. 実際に関数とグローバルを使った例
次の例は、設定値をグローバルにして、関数内で計算するパターンです。
PI = 3.14 # グローバルに定数として定義
def area(radius):
return PI * radius * radius
print("半径3の円の面積:", area(3))
半径3の円の面積: 28.26
このように、定数をグローバルに置いて関数内から使うのは安全で便利な使い方です。
まとめ
今回の記事では、Pythonプログラミングにおいて非常に重要な概念である「スコープ(変数の有効範囲)」について詳しく解説してきました。変数がどこで定義され、どこまでアクセス可能なのかを理解することは、バグの少ない、メンテナンス性の高いコードを書くための第一歩です。
スコープの基本:ローカルとグローバルの境界線
Pythonの変数には、大きく分けて「グローバルスコープ」と「ローカルスコープ」の2つが存在します。プログラムの最も外側で定義された変数はグローバル変数となり、プログラム内のどこからでも参照可能です。一方で、関数の内部で定義された変数はローカル変数と呼ばれ、その関数が実行されている間だけメモリ上に存在し、関数の外からは一切触れることができません。
この仕組みがあるおかげで、私たちは同じ変数名を異なる関数で使い回すことができます。例えば、複数の関数で「temp」という一時的な変数を使っても、それぞれがローカル変数であれば、互いに干渉することはありません。これは大規模な開発において、変数名の衝突を防ぐ極めて重要な役割を果たしています。
LEGBルールを知っておこう
Pythonが変数を探すときには「LEGB」と呼ばれる優先順位があります。これは以下の順序で変数を探しに行く仕組みです。
- L (Local): 現在の関数内のローカル変数
- E (Enclosing): 外側の関数のローカル変数(クロージャなど)
- G (Global): モジュールレベルのグローバル変数
- B (Built-in): Python標準の組み込み変数(lenやprintなど)
この優先順位を理解しておくと、「なぜこの変数が参照できないのか」「なぜ意図しない値が入っているのか」という問題に直面したときに、素早く原因を特定できるようになります。
globalキーワードの適切な使い方とリスク
関数の中からグローバル変数の値を書き換えたい場合には、globalキーワードを使用します。しかし、これには注意が必要です。グローバル変数を多用すると、プログラムのどの部分で変数が書き換えられたのかを追跡するのが難しくなり、予期せぬ挙動(サイドエフェクト)を引き起こす原因となります。
以下のサンプルコードで、グローバル変数の取り扱いの注意点を確認してみましょう。
# グローバル変数の定義
total_score = 0
def add_score(points):
# global宣言をすることで外部の変数にアクセス可能にする
global total_score
total_score += points
print(f"現在のスコア: {total_score}")
def reset_score():
# 関数内で新しく代入すると、global宣言がない限りローカル変数扱いになる
total_score = 0
print(f"関数内でのリセット(ローカル): {total_score}")
# 実行
add_score(10)
add_score(20)
reset_score()
print(f"最終的なグローバルスコア: {total_score}")
現在のスコア: 10
現在のスコア: 30
関数内でのリセット(ローカル): 0
最終的なグローバルスコア: 30
上記の例でわかる通り、reset_score関数内ではglobal宣言をしていないため、グローバル変数のtotal_scoreは書き換えられず、関数内だけで有効な新しいローカル変数が作られてしまっています。こうしたミスは初心者によく見られるポイントですので、意識して使い分ける必要があります。
実践的な設計のアドバイス
良いプログラムを書くための鉄則は「スコープをできるだけ狭く保つ」ことです。変数の寿命(有効期間)を短くすることで、コードを読み返す際に「この変数はどこに影響するのか」を考える範囲が狭まり、脳への負担を減らすことができます。
どうしても複数の関数間でデータを共有したい場合は、グローバル変数に頼るのではなく、関数の「引数」として渡し、「戻り値」として受け取る設計を優先しましょう。これにより、データの流れが明確になり、テストのしやすい綺麗なコードになります。
生徒
「先生、ありがとうございました!スコープの考え方がようやく整理できました。ローカル変数は関数の『中だけ』の秘密、グローバル変数はみんなで使う『共有スペース』のイメージですね。」
先生
「その通りです!非常に分かりやすい例えですね。共有スペースであるグローバル変数は便利ですが、誰かが勝手に物を動かすと全員が困ってしまいますよね。だからプログラムでも、なるべく個人のスペースであるローカル変数を使うのが安全なんです。」
生徒
「なるほど。だから実務ではグローバル変数はあまり使われないんですね。でも、定数みたいなものはグローバルに置いてもいいんでしょうか?」
先生
「ええ、消費税率や設定値のように、プログラム全体で共通して参照するだけの値ならグローバルに置くのが一般的ですよ。ただし、それを関数の中でコロコロ変えるのは避けましょうね。変える必要があるなら、基本は引数と戻り値を使うのがベストです。」
生徒
「引数と戻り値ですね!さっきのスコア計算のコードも、グローバル変数を使わずに引数で渡す形に書き換えて練習してみます!」
先生
「素晴らしい意気込みですね。実際にコードを書いてみて、エラーが出たときに『あ、これはスコープが原因かな?』と気づけるようになれば、脱・初心者ですよ!頑張ってくださいね。」