グローバル変数の扱い | ローカル変数とグローバル変数 | Python本格超入門

スポンサーリンク
スポンサーリンク
amazon
スマイルSALE
--:--:--
~
ad. 価格範囲を指定して商品を探せます

グローバル変数の扱い

Pythonのプログラムにおいて、変数がどこから読み書きできるかという「有効範囲」のことをスコープと呼びます。

その中でも、関数の外側(プログラムの一番上の階層)で定義され、プログラム全体からアクセスできる変数のことをグローバル変数と呼びます。非常に便利な仕組みである反面、使い方を誤ると予期せぬバグの温床になりやすいため、適切な管理が必要です。本記事では、その正しい扱い方について徹底解説します。

グローバル変数の基本(値の参照)

グローバル変数は、プログラム内のどこからでも、そしてどの関数の中からでも自由に「値の読み込み(参照)」を行うことができます。

# 関数の外側(最上階層)で定義されたグローバル変数
x = 100

def show_value():
    # 関数の中から外側のグローバル変数を読み込む
    print(x)  # 出力: 100

show_value()

このコードでは、関数 show_value 内に変数の定義がありませんが、Pythonは自動的に外側のグローバルスコープを探しに行き、変数 x の値である 100 を正しく読み取って表示します。

グローバル変数の変更(globalキーワード)

先ほどとは異なり、関数の中でグローバル変数の「値の書き換え(変更)」を行いたい場合は注意が必要です。Pythonでは、関数内で普通に変数を上書きしようとすると、同名の新しい「ローカル変数」がその場に作られてしまう仕様になっているためです。

関数内から本物のグローバル変数を書き換えるには、global キーワードを使って明示的に宣言する必要があります。

x = 100  # グローバル変数

def modify_value():
    # 【超重要】この関数内の x は、外のグローバル変数のことであると宣言
    global x
    x = 200  # グローバル変数を上書き
    print(f"関数内のx: {x}")  # 出力: 200

modify_value()
print(f"関数外のx: {x}")  # 出力: 200(関数外でも値が書き換わっている)

上記のコードの解説は以下の通りです。

  1. global x と記述することで、Pythonに対して「これ以降、この関数内で x という名前が登場したら、それはローカル変数ではなく、外にあるグローバル変数のことだよ」と教えることができます。
  2. その後に x = 200 とすることで、関数を抜けた後もプログラム全体で x の値が 200 に上書きされ続けます。

【初心者の落とし穴】globalを忘れたときに起きる不具合

もし global 宣言を忘れて関数内で値を書き換えようとすると、どのような問題が起きるかを実例で確認しましょう。

x = 100  # グローバル変数

def incorrect_modify():
    # global宣言を忘れた状態
    x = 200  # 💡Pythonは「関数内だけで使う新しいローカル変数x」を作ったと解釈する
    print(f"関数内のx: {x}")  # 出力: 200

incorrect_modify()
print(f"関数外のx: {x}")  # 出力: 100(外側のグローバル変数は100のまま変わっていない!)

このように、global キーワードを書き忘れると、外側の変数と名前が同じなだけの「別人の変数(ローカル変数)」が内部で勝手に誕生してしまいます。その結果、関数の中では値が変わっているのに外に出ると元に戻っている、という極めて気づきにくいバグを引き起こす原因になります。

グローバル変数とローカル変数の違い

2つの変数の性質やルールの決定的な違いのまとめです。

項目 グローバル変数 ローカル変数
定義される場所 関数の外側(トップレベル) 関数の内側
有効な範囲(寿命) プログラムが起動してから終了するまで全体 その関数が呼び出されてから、処理が終わるまで
関数内での変更方法 global 変数名 という明示的な宣言が必須 事前の宣言なしで、自由に書き換え可能

実務における注意点と「グローバル変数を使わない」設計思想

プログラミングの世界では、「グローバル変数の多用は原則として避けるべき(悪手)」とされています。理由は以下の3点にあります。

  • バグの原因追跡が困難になる:あらゆる関数から値を書き換えられてしまうため、「いつの間にか数値がおかしくなっている」というバグが起きた際、どの関数が犯人なのかを特定するのが非常に難しくなります。
  • コードの再利用性が下がる:特定のグローバル変数に依存した関数は、他のプログラムにコピペして使い回すことができなくなります。

そのため、実務ではグローバル変数の代わりに、以下のような安全なアプローチをとることが強く推奨されます。

# 推奨される設計:データの受け渡しは「引数」と「戻り値」で行う
def calculate_next_score(current_score):
    # 必要なデータは引数で受け取る
    new_score = current_score + 50
    # 結果は戻り値として安全に外へ送り返す
    return new_score

score = 100
# 関数を呼び出して結果をスマートに受け取る
score = calculate_next_score(score)
print(score)  # 出力: 150

まとめ

  • どこからでも読めるグローバル変数:関数の外で定義された変数は、プログラム全体から参照(読み込み)することができます。
  • 変更には global 宣言が必須:関数内部からグローバル変数の値を書き換えたい場合は、必ず global 変数名 と宣言しなければなりません。宣言を忘れると同名のローカル変数が作られてしまいます。
  • 引数と戻り値による対話を優先する:グローバル変数はプログラムの可読性を下げてしまうリスクがあるため、原則として「関数への引数渡し」と「return による結果の返却」を用いたクリーンな設計を徹底しましょう。