プログラミングにおいて、変数がどの場所から参照可能で、どこまで有効かという範囲を「スコープ」と呼びます。Pythonでは、関数の外側で定義された変数(グローバル変数/モジュール変数)を関数内部で扱う際に、少し特殊なルールが存在します。
「関数の中で外の変数を使おうとしたらエラーになった」「値を変えたはずなのに変わっていない」といったトラブルは、このスコープの理解不足が原因であることが多いです。
この記事では、関数内部からのグローバル変数の参照、更新、そして global 宣言の使い方について解説します。
1. グローバル変数の「参照」
関数の外側(モジュールレベル)で定義された変数は、関数の中から自由に**参照(読み取り)**することができます。特別な宣言は必要ありません。
# グローバル変数(モジュール変数)
APP_NAME = "Data Analyzer Pro"
def show_welcome_message():
"""
グローバル変数を参照して表示する関数
"""
# 関数内から外側の変数を読み取ることができる
print(f"Welcome to {APP_NAME}!")
# 関数の呼び出し
show_welcome_message()
実行結果:
Welcome to Data Analyzer Pro!
設定値や定数など、読み取り専用として使う分には、そのまま記述するだけで問題ありません。
2. ローカル変数の独立性(代入時の挙動)
注意が必要なのは、関数の中で変数に代入を行った場合です。
Pythonでは、関数内で変数に値を代入すると、その変数は自動的にその関数だけの**「ローカル変数」**として扱われます。たとえ外側に同じ名前の変数が存在していても、それとは無関係な新しい変数が関数内に作られます。
# グローバル変数
current_user = "Guest"
def login_admin():
# ここで代入を行っているため、'current_user' はこの関数固有のローカル変数となる
current_user = "Admin"
print(f"[関数内] ユーザー: {current_user}")
print(f"[開始前] ユーザー: {current_user}")
login_admin()
# 関数の外側の変数は変更されていない
print(f"[終了後] ユーザー: {current_user}")
実行結果:
[開始前] ユーザー: Guest
[関数内] ユーザー: Admin
[終了後] ユーザー: Guest
関数内で current_user を "Admin" に変更したつもりでも、実際には関数内だけのローカル変数が変更されただけで、外側のグローバル変数は "Guest" のままです。
3. global 宣言によるグローバル変数の「更新」
関数の中から外側のグローバル変数を書き換え(更新)たい場合は、global キーワードを使って、「この変数はローカルではなくグローバル変数を使います」と宣言する必要があります。
# アクセス数をカウントするグローバル変数
visitor_count = 0
def record_visit():
# global宣言を行う
global visitor_count
# これでグローバル変数を直接更新できる
visitor_count += 1
print(f"訪問を記録しました。現在のカウント: {visitor_count}")
# 関数の呼び出し
record_visit()
record_visit()
record_visit()
print(f"最終的なカウント: {visitor_count}")
実行結果:
訪問を記録しました。現在のカウント: 1
訪問を記録しました。現在のカウント: 2
訪問を記録しました。現在のカウント: 3
最終的なカウント: 3
global visitor_count と宣言したことで、関数内の visitor_count は外側の変数を指すようになり、+= 1 による更新が反映されました。
注意点:global の多用について
global を使うと、関数の外部の状態を簡単に変更できますが、多用は推奨されません。
- どこで変数が変更されたか追跡しにくくなる(バグの原因)。
- 関数の独立性が下がり、再利用やテストが難しくなる。
可能な限り、関数の引数として値を受け取り、戻り値(return)として結果を返す設計にすることが、保守性の高いコードを書くコツです。
まとめ
- 参照: 関数の外側の変数は、そのまま参照(読み取り)できます。
- 代入: 関数内で代入を行うと、それはローカル変数となり、外側の変数には影響しません。
- 更新: 外側の変数を書き換えたい場合は、関数内で
global 変数名と宣言します。
