このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

【Python入門】変数のスコープ

変数のスコープ

 Pythonにおける変数のスコープは、変数が「どこで」有効か(つまり参照可能か)を決定する重要な概念です。変数は定義された場所によってグローバル変数とローカル変数に分かれ、また、特定の文法(global文やnonlocal文)を用いることで、外部または上位スコープの変数にアクセスや変更を行うことができます。
 ここでは、変数のスコープの基本概念、グローバル変数とローカル変数の違い、さらにglobal文およびnonlocal文の使い方について、具体的なコード例と表を交えて解説します。

プログラムのダウンロード

 「ダウンロード」から、JupyterLab で実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。

1.変数のスコープの基本

1.1. グローバル変数

 グローバル変数は、関数の外側で定義される変数で、プログラム全体で有効です。関数内からも参照でき、必要に応じてglobal文を使って変更することも可能です。以下は、グローバル変数を利用した例です。

# グローバル変数の定義
greeting = "Welcome to Python!"

def say_hello():
    print("Inside say_hello:", greeting)  # グローバル変数greetingを参照

def say_goodbye():
    print("Inside say_goodbye:", greeting)

# 関数の呼び出し
say_hello()
say_goodbye()
print("Outside functions:", greeting)

実行結果

Inside say_hello: Welcome to Python!
Inside say_goodbye: Welcome to Python!
Outside functions: Welcome to Python!

解説

  • greeting は関数の外側で定義されているため、プログラム全体で参照可能です。
  • 関数 say_hello()say_goodbye() では、グローバル変数 greeting の値が正しく参照され、出力されます。

1.2. ローカル変数

 ローカル変数は、関数内で定義され、その関数内でのみ有効な変数です。異なる関数で同じ名前の変数を使用しても、それぞれ独立したローカル変数となります。

def morning_message():
    message = "Good Morning!"  # ローカル変数
    print("Inside morning_message:", message)

def evening_message():
    message = "Good Evening!"  # ローカル変数
    print("Inside evening_message:", message)

# グローバル変数とは異なる変数を外部で定義
message = "Hello, everyone!"
morning_message()
evening_message()
print("Global message:", message)

実行結果

Inside morning_message: Good Morning!
Inside evening_message: Good Evening!
Global message: Hello, everyone!

解説

  • 関数 morning_message()evening_message() 内で定義された message はローカル変数であり、それぞれの関数内でのみ有効です。
  • 外部で定義された message はグローバル変数であり、関数外でのみ参照されます。
  • ローカル変数は関数のスコープ内で優先されるため、関数内ではグローバル変数と同名の変数を使っても問題ありません。

1.3. global文とnonlocal文

 関数内でグローバル変数を変更したい場合は、global 文を用います。また、ネストされた関数において、外側の関数のローカル変数を変更するには nonlocal 文を使用します。

counter = 0  # グローバル変数

def increment():
    global counter  # グローバル変数counterを参照・変更する宣言
    counter += 1
    return counter

print("Global counter after increment:", increment())

def outer():
    value = 10  # outer関数のローカル変数
    def inner():
        nonlocal value  # outer関数のローカル変数valueを参照・変更する宣言
        value += 5
        return value
    print("Inner result:", inner())
    print("Outer value after inner call:", value)

outer()

実行結果

Global counter after increment: 1
Inner result: 15
Outer value after inner call: 15

解説

  • global counter により、increment 関数内でグローバル変数 counter にアクセスし、その値を変更しています。
  • nonlocal value により、inner 関数内で、外側の関数 outer のローカル変数 value を変更しています。
  • これにより、変数のスコープが関数の定義場所によってどのように影響を受けるかを明確に示しています。

2.変数のスコープの整理とまとめ

2.1. グローバル変数とローカル変数の比較

変数の種類定義場所有効範囲変更方法
グローバル変数関数の外側プログラム全体で有効global文を使用して変更可能
ローカル変数関数内またはブロック内その関数またはブロック内でのみ有効関数内のみで自由に使用可能

解説

  • グローバル変数は、どこからでもアクセスできるため、複数の関数で共通のデータを保持するのに適していますが、予期せぬ変更に注意が必要です。
  • ローカル変数は、その関数内に限定されるため、同名の変数を複数の関数で独立して使用でき、変数の衝突を防ぎます。

2.2. global文とnonlocal文の使い分け

  • global文は、関数内でグローバル変数を参照・変更する際に使用します。
  • nonlocal文は、ネストされた関数において、外側の関数のローカル変数を参照・変更する際に使用します。

まとめ

変数のスコープは、変数がどこで定義され、どこで有効かを決定する基本的な概念です。

  • グローバル変数は関数の外側で定義され、プログラム全体で使用可能ですが、変更する場合はglobal文を利用します。
  • ローカル変数は関数内で定義され、その関数内でのみ有効です。
  • global文nonlocal文を使うことで、特定のスコープの変数に対して明示的にアクセスや変更を行うことができます。

 これらの知識を正しく理解することで、変数の衝突を防ぎ、より安全で予測可能なプログラムを作成することができるようになります。