Python global宣言の完全ガイド:グローバル変数の使い方を徹底解説

Pythonのglobal宣言は、関数内でグローバル変数を変更する際に使用するキーワードです。変数のスコープを理解し、適切にグローバル変数を操作することは、効率的なプログラム設計において重要な知識です。

本記事では、Python初心者から中級者まで理解できるよう、global宣言の基本的な使い方から実践的な応用例まで詳しく解説します。

global宣言とは

global宣言は、関数内でグローバルスコープの変数を変更可能にするPythonのキーワードです。通常、関数内で変数に代入を行うとローカル変数が作成されますが、global宣言により既存のグローバル変数を変更できます。

基本構文

global 変数名
変数名 = 新しい値

基本的な使い方

global宣言なしの場合

count = 0  # グローバル変数

def increment():
    count = count + 1  # エラー:ローカル変数への参照前に代入
    return count

global宣言ありの場合

count = 0  # グローバル変数

def increment():
    global count
    count = count + 1
    return count

print(increment())  # 1

複数変数のglobal宣言

x = 10
y = 20

def modify_globals():
    global x, y
    x = 100
    y = 200

modify_globals()
print(x, y)  # 100 200

変数スコープの理解

ローカルスコープ

def local_example():
    local_var = "ローカル変数"
    print(local_var)

local_example()
# print(local_var)  # エラー:スコープ外

グローバルスコープ

global_var = "グローバル変数"

def access_global():
    print(global_var)  # 読み取りは可能

access_global()  # グローバル変数

global宣言での変更

message = "初期値"

def change_message():
    global message
    message = "変更後の値"

change_message()
print(message)  # 変更後の値

実践的な使用例

カウンター機能

counter = 0

def increment_counter():
    global counter
    counter += 1
    return counter

def reset_counter():
    global counter
    counter = 0

print(increment_counter())  # 1
print(increment_counter())  # 2
reset_counter()
print(counter)  # 0

設定管理

debug_mode = False

def enable_debug():
    global debug_mode
    debug_mode = True

def disable_debug():
    global debug_mode
    debug_mode = False

enable_debug()
print(f"デバッグモード: {debug_mode}")  # True

ゲームスコア管理

score = 0
high_score = 0

def add_points(points):
    global score, high_score
    score += points
    if score > high_score:
        high_score = score

add_points(100)
print(f"現在スコア: {score}, 最高スコア: {high_score}")  # 100, 100

よくある間違いと対処法

UnboundLocalError の回避

# 間違った例
total = 0
def wrong_function():
    print(total)  # エラーが発生する可能性
    total = 10

# 正しい例
total = 0
def correct_function():
    global total
    print(total)
    total = 10

読み取り専用の場合

config_value = "設定値"

def read_config():
    # 読み取りのみならglobal不要
    return config_value

def modify_config(new_value):
    # 変更する場合はglobal必要
    global config_value
    config_value = new_value

データ管理での活用

アプリケーション状態管理

app_state = {"logged_in": False, "user": None}

def login(username):
    global app_state
    app_state["logged_in"] = True
    app_state["user"] = username

def logout():
    global app_state
    app_state = {"logged_in": False, "user": None}

login("alice")
print(app_state)  # {'logged_in': True, 'user': 'alice'}

キャッシュ機能

cache = {}

def get_cached_data(key):
    return cache.get(key)

def set_cache(key, value):
    global cache
    cache[key] = value

set_cache("user_1", {"name": "Alice", "age": 25})
user_data = get_cached_data("user_1")

統計データの収集

request_count = 0
error_count = 0

def log_request():
    global request_count
    request_count += 1

def log_error():
    global error_count
    error_count += 1

def get_stats():
    return {"requests": request_count, "errors": error_count}

Web開発での活用

フラスコアプリの設定

app_config = {"debug": False, "port": 5000}

def configure_app(debug=None, port=None):
    global app_config
    if debug is not None:
        app_config["debug"] = debug
    if port is not None:
        app_config["port"] = port

configure_app(debug=True, port=8000)
print(app_config)  # {'debug': True, 'port': 8000}

セッション管理

active_sessions = {}

def create_session(session_id, user_data):
    global active_sessions
    active_sessions[session_id] = user_data

def destroy_session(session_id):
    global active_sessions
    if session_id in active_sessions:
        del active_sessions[session_id]

ファイル操作での活用

ログファイル管理

log_file = None

def open_log_file(filename):
    global log_file
    log_file = open(filename, 'a')

def write_log(message):
    global log_file
    if log_file:
        log_file.write(f"{message}\n")

def close_log_file():
    global log_file
    if log_file:
        log_file.close()
        log_file = None

パフォーマンスの考慮

計算結果のキャッシュ

fibonacci_cache = {}

def fibonacci(n):
    global fibonacci_cache
    if n in fibonacci_cache:
        return fibonacci_cache[n]
    
    if n <= 1:
        result = n
    else:
        result = fibonacci(n-1) + fibonacci(n-2)
    
    fibonacci_cache[n] = result
    return result

設定の一回読み込み

config_loaded = False
config_data = {}

def load_config():
    global config_loaded, config_data
    if not config_loaded:
        # 実際には設定ファイルから読み込み
        config_data = {"timeout": 30, "retries": 3}
        config_loaded = True
    return config_data

代替手段との比較

クラス変数を使用

class Counter:
    count = 0
    
    @classmethod
    def increment(cls):
        cls.count += 1
        return cls.count

# グローバル変数より管理しやすい
Counter.increment()  # 1

関数属性を使用

def counter():
    counter.count += 1
    return counter.count

counter.count = 0  # 関数に属性を追加
print(counter())  # 1

nonlocalキーワード

def outer_function():
    x = 10
    
    def inner_function():
        nonlocal x  # ローカルスコープの外側の変数を変更
        x = 20
    
    inner_function()
    return x

result = outer_function()  # 20

デバッグとテスト

グローバル変数の状態確認

def debug_globals():
    global_vars = {k: v for k, v in globals().items() 
                   if not k.startswith('_')}
    return global_vars

# 現在のグローバル変数を確認
current_globals = debug_globals()

テスト用のリセット関数

original_state = None

def save_global_state():
    global original_state
    original_state = {"count": count, "score": score}

def restore_global_state():
    global count, score, original_state
    if original_state:
        count = original_state["count"]
        score = original_state["score"]

良いプラクティス

最小限の使用

# 推奨:グローバル変数を最小限に
app_settings = {"theme": "dark"}

def update_theme(new_theme):
    global app_settings
    app_settings["theme"] = new_theme

# 非推奨:多数のグローバル変数
# global user, session, config, cache, etc.

命名規則

# グローバル変数は大文字で区別
CONFIG = {"debug": False}
SESSION_DATA = {}

def update_config(key, value):
    global CONFIG
    CONFIG[key] = value

初期化の明確化

# グローバル変数の初期化を明確に
INITIALIZED = False
DATA_STORE = {}

def initialize():
    global INITIALIZED, DATA_STORE
    if not INITIALIZED:
        DATA_STORE = {"items": [], "count": 0}
        INITIALIZED = True

実際のプロジェクトでの活用

CLI ツールの設定

verbose_mode = False

def set_verbose(enabled):
    global verbose_mode
    verbose_mode = enabled

def log_message(message):
    if verbose_mode:
        print(f"[LOG] {message}")

set_verbose(True)
log_message("処理を開始します")  # [LOG] 処理を開始します

ゲーム開発

game_state = "menu"
player_lives = 3

def start_game():
    global game_state, player_lives
    game_state = "playing"
    player_lives = 3

def lose_life():
    global player_lives, game_state
    player_lives -= 1
    if player_lives <= 0:
        game_state = "game_over"

API クライアント

api_token = None
base_url = "https://api.example.com"

def authenticate(token):
    global api_token
    api_token = token

def make_request(endpoint):
    if api_token:
        return f"GET {base_url}/{endpoint} with token"
    return "認証が必要です"

まとめ

Python の global 宣言は、関数内でグローバル変数を変更するための重要な機能です。適切に使用することで、アプリケーションの状態管理や設定管理を効率的に行えます。

重要なポイント:

  • 関数内でグローバル変数を変更する場合のみ必要
  • 読み取り専用の場合は不要
  • 最小限の使用を心がける
  • クラスや関数属性など代替手段も検討

本記事で紹介した様々な使用例を参考に、実際のプロジェクトで global 宣言を効果的に活用してください。適切な変数スコープの管理により、より保守性の高いコードを作成できるでしょう。

らくらくPython塾 – 読むだけでマスター

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<月1開催>放送作家による映像ディレクター養成講座

<オンライン無料>ゼロから始めるPython爆速講座