Python global宣言【書き換えの時に宣言が必要な理由】

Python
この記事は約6分で読めます。

こんにちは、ナナです。

Pythonにおいてグローバル変数を利用するときに「global宣言」が必要となるケースがあります。

Pythonを始めたばかりの人は、いったいなぜ「global宣言」なんてものが必要なんだろうと疑問に感じる方もいるでしょう。

ナナ

実はわたしも最初に見たときは「なんで必要なの?」と思ってました。

本記事では次の疑問点を解消する内容となっています。

本記事で学習できること
  • global宣言が必要なケースと不要なケースとは?
  • global宣言が必要となる理由とは?
  • global宣言が必要な理由と不要な理由を詳しく解説

それでは、「global宣言」について学んでいきましょう。

スポンサー

「global宣言」が必要なケースと、必要がないケースとは?

global宣言とはグローバル変数に対して、関数の中で値を書き換えるときに必要となる宣言です。

次のように使用されます。

def test_func():
    global x   # グローバル宣言
    x = 200    # グローバル変数のxを書き換え


x = 50         # グローバル変数の定義
test_func()
print("x:", x)

しかし、変数の値を読み取るだけであれば「global宣言」は必要ありません。

def test_func():
    print(x)   # グローバル変数を読みだして表示


x = 50         # グローバル変数の定義
test_func()

このように、グローバル変数の中身を参照するだけならば、「global宣言」なしでもグローバル変数「x」を値を参照することができます。

ここで、次の疑問が出てきます。

疑問

なぜ、グローバル変数を関数の中で書き換えるときだけ「global宣言」が必要となるのか?読み出すときはいらないのに…

ナナ

いったい、なぜ「global宣言」が必要となるのか?この記事で解説しましょう。

スポンサー

理由:「global宣言」がないと判断できないことがあるから

理由は簡単。「global宣言」がないと、あることが判断できず困ってしまうからです。

具体的に2つのプログラムを紹介しましょう。

プログラムその①

def test_func():

    x = 100
    # 関数の中で「x」を表示
    print("関数:", x) 

# グローバル変数の定義
x = 50

test_func()

# 関数の外で「x」を表示
print("ファイル:", x)
関数: 100
ファイル: 50

プログラムその②

def test_func():
    global x
    x = 100
    # 関数の中で「x」を表示
    print("関数:", x)

# グローバル変数の定義
x = 50

test_func()

# 関数の外で「x」を表示
print("ファイル:", x)
関数: 100
ファイル: 100

この2つのプログラムは非常に似ていますが、「global宣言」の有無によって実行された結果が変わります。

この2つのプログラムを判別するために「global宣言」が存在し、必要となる理由なのです。

スポンサー

詳細解説:「global宣言」が必要となる理由

この段階でピンと来る方もいると思いますが、もう少し丁寧に解説しましょう。

Pythonにおける変数定義の特徴 その①

Pythonは変数に対して明確な『変数定義』という構文が存在せず、「変数名への代入処理が現れた時点で、存在しない変数であれば変数定義となる」という特徴があります。

代入が「変数定義を伴う代入の場合」と「代入のみの場合」を明確に示しましょう。

x = 50          # グローバル変数の定義を伴う「代入」
x = 100         # 変数の値を書き換えるただの「代入」
print(x)

1行目の代入時点で「x」は存在していないため、変数「x」は『変数定義を伴う代入』と判断されます。

2行目の代入では、すでに変数「x」は存在しているため、変数定義を伴わない『ただの代入』として判断されます。

ナナ

変数の『定義』と『代入』の境界線があいまいなことが、「global宣言」が必要な理由につながっています。

Pythonにおける変数定義の特徴 その②

Pythonにおいては『グローバル変数』と同じ名前の変数を、『ローカル変数』として定義することが可能です。

def test_func():
    x = 100   # 同名のローカル変数「x」の定義
    print(x)  # ローカル変数の「x」である「100」が表示


x = 50        # グローバル変数の定義
test_func()

同名の変数名である場合は、関数内の処理ではローカル変数を参照して処理がされます。

ナナ

このように『グローバル変数』と『ローカル変数』の名前の重複は許されています。

2つの特徴によって引き起こされる問題と解決策

ここまでに説明した特徴①②によって「global宣言」が必要となる理由が判明します。

次のプログラムにおいて、test_func関数の中の「x」は次の2つの可能性があります。

  • ローカル変数を定義したとして処理したい
  • グローバル変数の値を変更したい
def test_func():
    x = 100			# この「x」をグローバルにしたい?ローカルにしたい?
    print("関数:", x) 

# グローバル変数の定義
x = 50

test_func()
print("ファイル:", x)

この2つのどちらを選択したいかは、皆さん次第でありプログラム側はどちらなのかは判断できません。

つまり、「global宣言」とは、この2つを切り分けるために必要なのです。

グローバル変数の中を書き換えたい場合は、「ここで書き換えている変数xは、グローバル変数ですよ!」と明示するために「global宣言」が必要なのです。

ナナ

わかりましたか?2つのケースを切り分けるための目印が「global宣言」なんです。

このように切り分けるための印のようなものは、プログラミングの世界ではよくあります。より深く考察することで、その理由がわかります。

スポンサー

なぜ、グローバル変数を読み取るだけのときは「global宣言」は不要なのか?

それでは、続いてグローバル変数を読み取る場合には「global宣言」が不要な理由を解説しておきましょう。

ここまでの内容を理解していれば、結構簡単な理由なんです。

もう一度、読み取りしているプログラムをじっくりと見てみましょう。

def test_func():
    print(x)


x = 50         # グローバル変数の定義
test_func()

test_func関数の中には、変数「x」への代入がないため、変数「x」はローカル変数であることがありえません。

これこそが読み取り時においては「global宣言」が不要な理由です。

ナナ

皆さん、わかりましたか?

言語仕様というものは、必ず何かを実現するために決められたルールであり、意味のないルールなんてないのです。理由を知ることが「本当の意味で使いこなす」ということなんです。

Python よく使う機能解説まとめ