🫣

[Python]グローバル変数を関数内で変更するとエラーが発生する😢

2024/08/21に公開

はじめに

競技プログラミングの問題を解いていて、グローバル変数を関数内で変更するとエラーが発生し
色々調べたので自分用にまとめます。

エラーの内容

実際のコードはロジックが多いので、かなり簡潔にしたコードが以下

count = 0  # これはグローバル変数

def my_function():
    count = count + 1  # ここでエラーが発生します
    print(count)

my_function()

# エラーの内容は以下
# UnboundLocalError: cannot access local variable 'count'
# =ローカル変数countにアクセスできないよエラー

エラー原因

  • エラーの原因はPythonが次のように解釈するため
    • count = count + 1 の左側で、count に何かを代入しようとしている。
    • 代入を行おうとする際、Pythonはこの count を「ローカル変数」だとみなす。
    • しかし、その count がまだ定義されていないため、エラーが発生。
  • Pythonは、関数内で一度でも代入を行った変数をローカル変数として扱います。そのため、count という名前の変数をグローバル定義していても、関数内でcount = .とすると変数countをローカル変数だとみなし、初期化前に利用しようとするためエラーが発生する

解決策

よく使われる解決策は2つ

  1. Globalキーワードを使う
count = 0  # グローバル変数

def my_function():
    global count  # countはグローバル変数であることを宣言
    count = count + 1  # これでエラーが発生しなくなる
    print(count)
  1. 関数の引数にグローバル変数を使う
def my_function(count):
    count = count + 1  # countの値を更新
    print(count)
    return count  # 更新後のcountを返す

count = 0  # グローバル変数
count = my_function(count)  # 関数呼び出し時にcountを渡し、戻り値で更新

どちらを選ぶべきか?

小さなスクリプトや単純な処理では、global キーワードを使っても問題ないかと思います。特に、グローバル変数が少なく、依存関係が明確であれば、コードがシンプルであることが優先されるためです。

大規模なプログラムや関数の再利用を考慮する場合は、引数に変数を渡す方法の方が一般的に推奨されます。これにより、関数が独立して動作するようになり、モジュール性が高まり、テストがしやすくなります

Discussion