Python global宣言入門|関数内でグローバル変数を使う
Python global宣言の使い方を初心者向けに解説。ローカル変数とグローバル変数の違いから実践的な使い方、注意点まで詳しく説明します。
Python global宣言入門|関数内でグローバル変数を使う
みなさん、Pythonで関数を作っていて変数のことで困ったことはありませんか?
「関数の中で変数を変更したいのに、エラーが出る」 「UnboundLocalErrorって何?」 「関数の外で作った変数を使いたいけど、どうすればいいの?」
こんな疑問、よくありますよね。
実は、Pythonにはglobal宣言という便利な機能があるんです。 これを使えば、関数の中から外の変数を自由に変更できるようになります。
この記事では、global宣言の使い方を初心者向けにわかりやすく解説します。 変数のスコープから実践的な活用方法まで、一緒に学んでいきましょう!
global宣言って何?
global宣言は、関数の中でグローバル変数を変更するためのPythonのキーワードです。
簡単に言うと、「この変数は外で作ったものを使いますよ」という宣言なんです。
ローカル変数とグローバル変数の違い
まず、変数のスコープ(有効範囲)を理解しましょう。
# グローバル変数(どこからでも見える)counter = 0
def increment(): # これだとエラーになる # counter = counter + 1 # UnboundLocalError
def increment_correct(): global counter # これがglobal宣言 counter = counter + 1
print(f"初期値: {counter}")increment_correct()print(f"変更後: {counter}")
このコードを実行すると、こうなります。
初期値: 0
変更後: 1
global counter
と宣言することで、関数内からグローバル変数を変更できます。
宣言がないと、Pythonは新しいローカル変数を作ろうとしてエラーになっちゃいます。
基本的な使い方
global宣言の書き方
global宣言の基本的な書き方はとてもシンプルです。
def function_name(): global 変数名 # 変数を使用・変更
実際の例を見てみましょう。
# ゲームのスコア管理total_score = 0game_count = 0
def add_score(score): global total_score, game_count total_score += score game_count += 1
# スコアを追加してみようadd_score(100)add_score(150)add_score(120)
print(f"合計スコア: {total_score}")print(f"ゲーム回数: {game_count}")print(f"平均スコア: {total_score / game_count}")
実行結果はこちらです。
合計スコア: 370
ゲーム回数: 3
平均スコア: 123.33333333333333
global total_score, game_count
のように、複数の変数を同時に宣言できます。
カンマで区切って並べるだけです。
読み取り専用なら宣言不要
グローバル変数を読み取るだけなら、global宣言は必要ありません。
app_name = "My Application"version = "1.0.0"
def show_app_info(): # 読み取り専用なら宣言不要 print(f"アプリ名: {app_name}") print(f"バージョン: {version}")
def update_version(new_version): global version # 変更するときは宣言が必要 version = new_version
show_app_info()update_version("1.1.0")show_app_info()
実行すると、こんな感じになります。
アプリ名: My Application
バージョン: 1.0.0
アプリ名: My Application
バージョン: 1.1.0
読み取り専用なら、そのまま使えちゃいます。 変更するときだけglobal宣言が必要なんですね。
実践的な活用例
カウンター機能
関数が呼ばれた回数をカウントする機能を作ってみましょう。
# カウンター変数call_count = 0
def reset_counter(): global call_count call_count = 0 print("カウンターをリセットしました")
def increment_counter(): global call_count call_count += 1 print(f"関数が {call_count} 回呼び出されました")
def get_count(): return call_count
# 使ってみようincrement_counter() # 1回目increment_counter() # 2回目increment_counter() # 3回目print(f"現在のカウント: {get_count()}")reset_counter()print(f"リセット後のカウント: {get_count()}")
実行結果はこちらです。
関数が 1 回呼び出されました
関数が 2 回呼び出されました
関数が 3 回呼び出されました
現在のカウント: 3
カウンターをリセットしました
リセット後のカウント: 0
複数の関数が同じグローバル変数を共有して使っています。
設定管理システム
アプリケーションの設定を管理するシステムを作ってみましょう。
# グローバル設定変数debug_mode = Falselog_level = "INFO"max_connections = 100
def enable_debug(): global debug_mode, log_level debug_mode = True log_level = "DEBUG" print("デバッグモードを有効にしました")
def disable_debug(): global debug_mode, log_level debug_mode = False log_level = "INFO" print("デバッグモードを無効にしました")
def set_max_connections(count): global max_connections if count > 0: max_connections = count print(f"最大接続数を {count} に設定しました") else: print("最大接続数は正の数である必要があります")
def show_settings(): print("=== 現在の設定 ===") print(f"デバッグモード: {debug_mode}") print(f"ログレベル: {log_level}") print(f"最大接続数: {max_connections}")
# 設定を変更してみようshow_settings()enable_debug()set_max_connections(200)show_settings()
実行すると、こんな結果になります。
=== 現在の設定 ===
デバッグモード: False
ログレベル: INFO
最大接続数: 100
デバッグモードを有効にしました
最大接続数を 200 に設定しました
=== 現在の設定 ===
デバッグモード: True
ログレベル: DEBUG
最大接続数: 200
関数を通じて設定を管理できて便利ですね。
よくある間違いと対策
global宣言を忘れた場合
global宣言を忘れると、UnboundLocalErrorが発生します。
score = 0
def bad_function(): # これはエラーになる try: score = score + 10 # UnboundLocalError except UnboundLocalError as e: print(f"エラー: {e}") print("global宣言が必要です")
def good_function(): global score score = score + 10 # これは正常に動作
print(f"初期スコア: {score}")bad_function()print(f"エラー後のスコア: {score}")good_function()print(f"正常処理後のスコア: {score}")
実行結果を見てみましょう。
初期スコア: 0
エラー: local variable 'score' referenced before assignment
global宣言が必要です
エラー後のスコア: 0
正常処理後のスコア: 10
変数を変更する前に、必ずglobal宣言を行いましょう。
同じ名前の変数で混乱
同じ名前のローカル変数とグローバル変数があると混乱が起こります。
message = "グローバルメッセージ"
def confusing_function(): print(f"関数開始時: {message}") # グローバル変数を参照 message = "ローカルメッセージ" # ローカル変数を作成 print(f"ローカル変数設定後: {message}")
def clear_function(): global message print(f"関数開始時: {message}") # グローバル変数を参照 message = "変更されたグローバルメッセージ" # グローバル変数を変更 print(f"グローバル変数変更後: {message}")
print(f"初期状態: {message}")confusing_function()print(f"confusing_function後: {message}") # 変更されていないclear_function()print(f"clear_function後: {message}") # 変更されている
実行結果はこちらです。
初期状態: グローバルメッセージ
関数開始時: グローバルメッセージ
ローカル変数設定後: ローカルメッセージ
confusing_function後: グローバルメッセージ
関数開始時: グローバルメッセージ
グローバル変数変更後: 変更されたグローバルメッセージ
clear_function後: 変更されたグローバルメッセージ
変数名の衝突を避けるために、明確な命名を心がけましょう。
もっと良い方法もある
global宣言は便利ですが、他にももっと良い方法があります。
クラスを使った状態管理
class GameState: def __init__(self): self.score = 0 self.level = 1 self.lives = 3 def add_score(self, points): self.score += points if self.score >= self.level * 1000: self.level_up() def level_up(self): self.level += 1 print(f"レベルアップ!現在レベル: {self.level}") def lose_life(self): self.lives -= 1 if self.lives <= 0: print("ゲームオーバー") def show_status(self): print(f"スコア: {self.score}, レベル: {self.level}, ライフ: {self.lives}")
# 使ってみようgame = GameState()game.show_status()game.add_score(500)game.add_score(600)game.show_status()
実行結果はこちらです。
スコア: 0, レベル: 1, ライフ: 3
レベルアップ!現在レベル: 2
スコア: 1100, レベル: 2, ライフ: 3
クラスを使うと、より構造化された状態管理ができます。
辞書でまとめて管理
# 設定を辞書でまとめるconfig = { "debug": False, "log_level": "INFO", "max_users": 100, "timeout": 30}
def update_config(key, value): global config if key in config: old_value = config[key] config[key] = value print(f"{key}を {old_value} から {value} に変更しました") else: print(f"未知の設定項目: {key}")
def get_config(key): return config.get(key, None)
def show_all_config(): print("=== 全設定 ===") for key, value in config.items(): print(f"{key}: {value}")
# 使ってみようshow_all_config()update_config("debug", True)update_config("max_users", 200)show_all_config()
実行結果はこちらです。
=== 全設定 ===
debug: False
log_level: INFO
max_users: 100
timeout: 30
debugを False から True に変更しました
max_usersを 100 から 200 に変更しました
=== 全設定 ===
debug: True
log_level: INFO
max_users: 200
timeout: 30
辞書を使うと、設定項目をまとめて管理できて便利です。
まとめ
Python global宣言は、関数内でグローバル変数を変更するための重要な機能です。
今回学んだポイント
- global宣言で関数内からグローバル変数を変更できる
- 読み取り専用の場合はglobal宣言は不要
- 複数の変数を同時にglobal宣言可能
- UnboundLocalErrorを避けるために適切な宣言が必要
- クラスや辞書を使った代替手段もある
global宣言を理解すると、変数のスコープを適切に管理できるようになります。 ただし、使いすぎると複雑になるので、状況に応じて他の方法も検討してみてください。
まずは基本的な使い方から始めて、徐々に応用的な技術も身につけていきましょう!