globalの概要
| 関数内からグローバル変数を使うPython予約語 | ||
|
global 概要 わかりやすく説明 |
||
|
globalの考え方をイメージで理解

globalの基本的な使い方
関数の外側でゼロ管理されている counter という大元の変数に対し、関数の中からアクセスして数値をプラス1加算する最も標準的な記述です。
# global を使ったグローバル変数の変更
counter = 0 # 関数の外にある変数(グローバル変数)
def increment():
global counter # 外の世界の「counter」を直接イジることを宣言
counter += 1 # 大元の変数が直接プラス1される
increment()
print(counter) # 結果: 1 (外側の変数も連動して書き換わっています)
global counterの防網によって、インデントの内部と外部の変数が完全に同一のメモリ空間として同期されます。
globalがない場合の挙動(初心者がハマる罠)
もし global 宣言の記述を忘れてしまうと、Pythonは「関数の中に同姓同名の別人が新しく引っ越してきた」と自動解釈してしまいます。
# global の宣言を忘れた場合
counter = 0 # 外の変数(グローバル変数)
def increment_fail():
counter = 1 # 💡外とは無関係の「新しいローカル変数」が関数内で勝手に作られる
print(f"関数内の counter: {counter}") # 結果: 1
increment_fail()
print(f"グローバルの counter: {counter}") # 結果: 0 (外側は大元の設定のまま微動だにしていません!)
globalを使った複数変数の同時操作
変更したいグローバル変数が複数ある場合、ひとマスの global の後ろにカンマ , で並べることによって、一括で操作対象に指定できます。
# 複数のグローバル変数を同時に指定
x = 10
y = 20
def update_globals():
global x, y # xとyの両方を外の宇宙から引っ張ってくる
x += 5
y *= 2
update_globals()
print(x, y) # 結果: 15 40
【重要】値の「読み取り(参照)」だけならglobalは不要
Pythonの文法規則として、外側の変数の値を「変更(再代入)」するときだけ global の明示が必要になります。ただ単に中身を覗き見てプリントしたり、条件分岐に使うだけ(読み取り専用)であれば、global の記述は一切不要です。
# 読み取りだけのケース
system_status = "稼働中"
def check_status():
# データを書き換えないのであれば、宣言なしで外のグローバル変数をそのまま参照可能
print(f"現在のシステムステータスは {system_status} です")
check_status() # 結果: 現在のシステムステータスは 稼働中 です
globalの注意点
- UnboundLocalErrorを引き起こす順序の罠(最重要バグ):関数内で
global宣言を記述していない状態のまま、同じ変数に対して「参照」と「代入」を混在させると、Pythonのコンパイラが変数の所属を見失い、UnboundLocalErrorという深刻なエラーを吐き出して処理が即座にクラッシュします。# 【クラッシュする致命的な失敗コード】 score = 100 def adjust_score(): # 宣言がないのに、ここで外の score を見ようとする print(score) # しかし同じ関数内で代入も行っているため、Pythonが「ローカル変数なのか?」と大混乱を起こす score = score + 10 adjust_score() # エラー内容: UnboundLocalError: local variable 'score' referenced before assignment # 【globalを明示して位置関係を整理した正しい対策コード】 def adjust_score_safe(): global score # 最初に所属をグローバルであると断定する print(score) score = score + 10 # 安全に上書きが成功します adjust_score_safe() - 関数の独立性(カプセル化)が破壊されテスト不能になる:優れたプログラムにおける関数とは、引数(インプット)を受け取って戻り値(アウトプット)を返す「単体で動作する綺麗なレゴブロック」であるべきです。
globalを多用したコードは、外側の変数の状態に依存(密結合)してしまうため、その関数単体をテストすることが困難になり、システム拡張時の最大の足かせになります。
globalのよくある質問
- Q: 実務において `global` を使わずに、関数の外にある変数を安全にアップデートする「プロ推奨の綺麗な書き方」を教えてください。
- A:
globalで外側を汚染するのではなく、関数側はreturn(戻り値)で加工済みの値をお土産として外に放り出し、外側のメインストリームで変数に上書き代入する設計が実務における100点満点の綺麗なアプローチです。# 【アンチパターン:変化の追跡がしにくい悪いコード】 user_points = 50 def add_points_bad(): global user_points user_points += 10 add_points_bad() # 【プロ推奨:引数と戻り値で完結させる洗練された対策コード】 user_points = 50 def add_points_good(current_points): return current_points + 10 # 関数内は引数の処理だけに集中し、外の世界を傷つけない # 外側の主導権を持ったラインで、安全に再代入を行う(globalが不要で明快!) user_points = add_points_good(user_points) print(user_points) # 結果: 60 - Q: 関数が何重にも入れ子(ネスト)になっている状況で、「一番外側」ではなく「1つ親の階層の関数」にある変数を書き換えたいときも `global` を使いますか?
- A: いいえ、そこには別の専用キーワードが存在します。
globalは、いかなる深さからであっても、ファイルを貫通して最外層の「モジュール直下の変数」に繋ぐための命令です。そうではなく、「関数の中にある関数の、そのさらに親の関数」という1つ外側の階層の変数をロックオンしたい場合は、globalではなくnonlocalという別の予約語を使用しなければならないルールになっています。
まとめ
global は、関数の壁を強引に破壊して最外層のグローバルスコープにあるデータを直接書き換えるための強力な予約語です。
- 関数内部からグローバル変数に対して「値の代入・変更」を加えて同期させる際に宣言が必須となる。
- 宣言を怠ったまま代入を試みると、関数内限定の同姓同名のローカル変数が独立生成され、外側への書き換え要求は完全に無視される。
- コード全体の可読性と、不意なデータ書き換えバグを防ぐため、実務での利用は共通設定ファイルの読み込みなど最低限の局面に絞り、基本は引数と
returnを中心としたクリーンな設計を意識する。
スコープの境界線システムを正確に統治し、global に依存しない頑丈で美しい条件ロジックを組み立てられるようになりましょう。