[解決!Python]global文で変数がグローバルであると宣言するには解決!Python

Pythonでは関数などの内部からグローバル変数の値を変更するにはglobal文でそれがグローバル変数であると宣言する必要がある。

» 2023年10月10日 05時00分 公開
[かわさきしんじDeep Insider編集部]
「解決!Python」のインデックス

連載目次

g_var = 'deep insider'

def myfunc1():
    # g_varは自由変数でグローバルスコープのg_varを参照する
    print(f'in myfunc1 g_var: {g_var}'# in myfunc1 g_var: deep insider

print(f'module top g_var: {g_var}'# module top g_var: deep insider
myfunc1()  # in myfunc1 g_var: deep insider

def myfunc2():
    g_var = 'atmarkit'  # 関数のローカルスコープに変数g_varを定義
    print(f'in myfunc2 g_var: {g_var}')

print(f'module top g_var: {g_var}'# module top g_var: deep insider
myfunc2()  # in myfunc2 g_var: atmarkit
print(f'module top g_var: {g_var}'# module top g_var: deep insider

def myfunc3():
    global g_var  # 変数g_varはグローバル変数
    print(f'in myfunc3 g_var: {g_var}')
    g_var = 'windows insider'

print(f'module top g_var: {g_var}'# module top g_var: deep insider
myfunc3()  # in myfunc3 g_var: deep insider
print(f'module top g_var: {g_var}'# module top g_var: windows insider

def myfunc4():
    print(f'in myfunc4 g_var: {g_var}'# SyntaxError
    global g_var  # global文で列挙する前に変数g_varを使ってはいけない
    g_var = 'something'

def myfunc5():
    global g_var2  # 未定義のグローバル変数をglobal文で宣言
    g_var2 = 'itmedia'
    print(f'in myfunc5 g_var2: {g_var2}')

myfunc5()  # in myfunc5 g_var2: itmedia
print(f'module top g_var2: {g_var2}'# module top g_var2: itmedia


global文とは

 Pythonのglobal文とは次のようなものだ。

  • 関数内などで使用する変数がグローバル変数であることを宣言するために使用する
  • グローバル宣言していない場合、グローバル変数は参照可能だが、代入はできない
  • 関数内などで、グローバル宣言をせずに、グローバル変数と同名の変数に代入を行うと、ローカル変数が新たに作成される
  • グローバル宣言する変数は、global文よりも前に使うことはできない
  • モジュールのトップレベルで未定義の変数をグローバル宣言すると、その変数がグローバル変数として定義される

グローバル変数とglobal文

 グローバル変数はモジュールのトップレベルで定義される変数のことだ。この変数はモジュール内の任意の位置から参照できる。以下に例を示す。

g_var = 'deep insider'

def myfunc1():
    # g_varは自由変数でグローバルスコープのg_varを参照する
    print(f'in myfunc1 g_var: {g_var}'# in myfunc1 g_var: deep insider

print(f'module top g_var: {g_var}'# module top g_var: deep insider
myfunc1()  # in myfunc1 g_var: deep insider


 この例では、モジュールのトップレベルで変数g_varに'deep insider'を代入している(グローバル変数)。myfunc1関数の内部では特にローカル変数を定義することなく、変数g_varにアクセスをしている。これはモジュールのトップレベルで定義されたグローバル変数g_varを参照するものだ。

 このようにグローバル変数は、モジュールの任意の位置で参照できる。ただし、関数の定義などにより作成されたコードブロック内でグローバル変数に代入をしようとすると、そのコードブロック内で同名のローカル変数が定義され、グローバル変数は見えなくなる。

def myfunc2():
    g_var = 'atmarkit'  # 関数のローカルスコープに変数g_varを定義
    print(f'in myfunc2 g_var: {g_var}')

print(f'module top g_var: {g_var}'# module top g_var: deep insider
myfunc2()  # in myfunc2 g_var: atmarkit
print(f'module top g_var: {g_var}'# module top g_var: deep insider


 この例では、myfunc2関数の先頭で変数g_varに'atmarkit'を代入しているが、これはモジュールのトップレベルで定義されているグローバル変数g_varへの代入ではない。そうではなく、myfunc2関数にローカルな変数g_varを定義して、そこに文字列を代入している。これにより同名のグローバル変数は見えなくなり、関数内で変数g_varの値を参照したり変更したりすると、ローカル変数g_varがその対象となり、変数の値の変更は関数内に留まり、グローバル変数の値が変更されることはない。

 そのため、関数定義後にある2つのprint関数呼び出しではグローバル変数g_varの値が参照されて、'deep insider'がその値として使われる。それらに挟まれているmyfunc2関数呼び出しでは、内部のprint関数の呼び出しでローカル変数g_varの値('atmarkit')が使われる。

 関数の内部などからグローバル変数の値を変更するにはglobal文を使って、その変数がグローバル変数であることを宣言する必要がある。

def myfunc3():
    global g_var  # 変数g_varはグローバル変数
    print(f'in myfunc3 g_var: {g_var}')
    g_var = 'windows insider'

print(f'module top g_var: {g_var}'# module top g_var: deep insider
myfunc3()  # in myfunc3 g_var: deep insider
print(f'module top g_var: {g_var}'# module top g_var: windows insider


 この例ではmyfunc3関数の冒頭でglobal文により変数g_varがグローバル変数であることを宣言している。そのため、その後のprint関数呼び出しではグローバル変数g_varの値('deep insider')が使われる。また、最後の代入文ではグローバル変数g_varに'windows insider'が代入される。

 関数定義の直後のprint関数が呼び出される時点では、グローバル変数g_varの値は'deep insider'なのでこれが出力される。その後にあるmyfunc3関数を呼び出すと、グローバル変数g_varの値である'deep insider'が使われる。そして、グローバル変数に新しい値('windows insider')が代入されるので、最後のprint関数呼び出しでは'windows insider'が出力される。

 なお、global文で列挙する識別子(変数名)は、それよりも前の位置で使用することはできない。

def myfunc4():
    print(f'in myfunc4 g_var: {g_var}'# SyntaxError
    global g_var  # global文で列挙する前に変数g_varを使ってはいけない
    g_var = 'something'


 この例では、global文で変数g_varがグローバルであると宣言するよりも前に、その値を参照しようとしているが、これは許されず、関数を定義する段階でSyntaxError例外が発生する。

 モジュールのトップレベルで定義していないグローバル変数であってもグローバル宣言を行える。このときには、その変数は新たに定義される。

def myfunc5():
    global g_var2  # 未定義のグローバル変数をglobal文で宣言
    g_var2 = 'itmedia'
    print(f'in myfunc5 g_var2: {g_var2}')

myfunc5()  # in myfunc5 g_var2: itmedia
print(f'module top g_var2: {g_var2}'# module top g_var2: itmedia


 この例では、変数g_var2がグローバル変数であると宣言しているが、この変数はモジュールのトップレベルではまだ定義されていない。しかし、このglobal文は例外を発生せずに、新たにグローバル変数g_var2が定義される。

 そのため、myfunc5関数を呼び出した後で、変数g_var2を参照すると、myfunc5関数で代入された'itmedia'がその値となる。

「解決!Python」のインデックス

解決!Python

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。