「なんでここで変数が使えないの?」
プログラムを作成していると、定義したはずの変数がエラーで認識されず、戸惑ってしまう場面に遭遇することがありますよね。
これはPythonにおけるスコープ(有効範囲)という仕様です。
スコープの概念は、オフィスでの私物(個人の机の中)と共有備品(壁掛け時計)の違いに置き換えて考えると、直感的に理解しやすくなります。
ここでは、ローカル変数とグローバル変数の仕組みや動作の違い、そしてなぜ変数の有効範囲を分ける必要があるのかを順を追って解説していきます。
変数の有効範囲を決めるスコープの概念
プログラム内で扱われる変数には、それぞれ参照できる場所と寿命が定められています。これをスコープと呼びます。
机の中のメモ帳にあたるローカル変数
関数(def)の内部で定義された変数は、ローカル変数と呼びます。
これは個人のデスクの引き出しにしまってあるメモ帳のようなものであり、その関数を実行している間だけ存在し、関数内部からのみ使用できます。隣の人(関数の外や別の関数)が勝手に参照することはできません。
オフィスの壁掛け時計にあたるグローバル変数
一方、関数の外側(プログラムの最上位レベル)で定義された変数は、グローバル変数と呼ばれます。
これはオフィスの壁に掛かっている時計のようなもので、プログラム全体のどの関数からでも参照できます。
コードで確認する変数の動作とエラーの仕組み
実際のコードを通して、それぞれの変数がどのように振る舞うのかを確認してみましょう。
①ローカル変数を関数の外から参照した場合
ローカル変数は関数の処理が完了するとメモリ上から破棄されます。そのため、関数の外から呼び出そうとすると未定義エラー(NameError)が発生します。
def office_work():
# 関数内部で定義したローカル変数
my_memo = "明日は10時出社"
print(f"関数内での確認: {my_memo}")
# 関数の実行
office_work()
# 関数の外側からローカル変数を参照しようとする
# ここで未定義エラーが発生します
print(f"関数外からの確認: {my_memo}")
実行結果:
関数内での確認: 明日は10時出社
NameError: name 'my_memo' is not defined
関数が終了した時点で my_memo は消去されているため、外側からは存在しないものとして扱われます。
②グローバル変数を複数の関数から参照した場合
グローバル変数は、複数の異なる関数から参照することができます。
# プログラムの最上位で定義したグローバル変数
office_clock = "12:00"
def meeting_room():
# 会議室(関数1)から共通の変数を参照
print(f"会議室から確認: {office_clock}")
def my_desk():
# 自席(関数2)からも共通の変数を参照
print(f"自席から確認: {office_clock}")
meeting_room()
my_desk()
実行結果:
会議室から確認: 12:00
自席から確認: 12:00
どの関数からでも共通の値 12:00 が正しく参照できていることが分かります。
すべてを変数共有にしない理由と設計の重要性
「全部グローバル変数(共有備品)にすれば便利じゃん!」
そう思いませんか?しかし、すべての変数をグローバルにしてしまうと、プログラムの保守や修正が非常に難しくなります。
これは、社員全員が1つのホワイトボードのみに各自で勝手に業務メモを書き込み、作業を進めるような状況に似ています。
誰かが誤って内容を書き換えたり消去したりした場合、どこで予期せぬ変更が起きたのかを突き止めるのが非常に困難ということです。
そのため、プログラミングでは以下の原則を守ることが推奨されています。
- 基本はローカル変数を使用し、影響範囲を最小限に留める
- 関数の入力(引数)と出力(戻り値)を明確にし、関数ごとの独立性を高める
- 意図しない値の書き換えを防ぐことで、バグの発生を抑えデバッグを容易にする
変数の有効範囲を適切に意識することで、予期せぬ不具合を防ぎ、見通しの良い安全なコード設計につながります。
有効範囲を意識してぜひ取り入れてみてください!
Pythonの本は種類が多すぎて、業務効率化に使えるのか見分けるのが大変ですよね。実務自動化に5年以上携わってきた私が、「デスクワークの自動化に即戦力になった本」を厳選して紹介します。失敗しない1冊を見つけたい方は、ぜひ参考にしてみてください。

コメント