Pythonは名前だらけでは、Pythonの変数も関数も結局はみんな名前、という解説をしました。この特徴を使って、Pythonのちょっとおもしろい挙動を調べてみましょう。
Pythonの変数には、グローバル変数とローカル変数があります。関数の内部で定義した変数はローカル変数、それ以外はグローバル変数となります。
global_var = "これはグローバル変数です。"
def func():
    local_var = "これはローカル変数です"
グローバル変数は同じモジュール内なら誰でも参照できますが、ローカル変数は関数内部でしか参照できません。
また、関数の内部で定義した変数でも、global と宣言された変数はグローバル変数になります。
variable = "これはグローバル変数です。"
def func():
    global variable
    variable = "グローバル変数を更新しました!"
ここで、func() を呼び出す前の variable の値は、 "これはグローバル変数です。" です。
print(variable)
func() を呼び出すと、グローバル変数 variable は更新されて、 "グローバル変数を更新しました!"になります。
func()
print(variable)
def func():
    def local_func():
        print("ローカル関数です!")
関数 func() の中で、もう一つの関数 local_func() を定義しています。普通の変数とおなじように、local_func() もローカル変数と同じ扱いで、関数 func() 内からしか呼び出せません。
では、local_func という名前を global 宣言するとどうなるでしょう?
def func():
    global local_func
    def local_func():
        print("ローカル関数です!")
Pythonは名前だらけでしつこく繰り返しましたが、Pythonでは変数の代入も関数の定義も、結局は名前を定義するだけのことです。関数定義でできた名前も、変数の定義と同じ仕組みで処理されます。
ということは、func()を実行すると……
func()
local_func()
関数名 local_func も、普通の変数と同じようにグローバル変数となり、関数の外側からも呼び出せるようになりました。
def func():
    global local_func
    def local_func():
        print("ローカル関数です!")
という処理は、
def func():
    def work_file_name():
        print("ローカル関数です!")
    global local_func
    local_func = work_file_name
と同様、と考えるとわかりやすいかもしれません。
あまり意味のないglobalの使い方ですが、Pythonが変数定義も関数定義も区別していない、ということがよく分かると思います。
import 文でも、同じような使い方ができます。変数名 sys を global宣言してから、 標準モジュール sys をインポートするとどうなるでしょう?
def func():
    global sys  # 変数名 sys をグローバル宣言
    import sys  # sys をインポート
func()
print(sys)
Pythonにはもう一つ、nonlocal という宣言というのがあります。こちらはローカル関数の中で変数を定義したとき、ローカル変数ではなく、その関数の外側のローカル変数を変更する、という宣言です。
def func():
    var1 = 1
    var2 = 2
    
    def local_func():
        nonlocal var2
        var1 = "three" # local_func の var1 を更新
        var2 = "four"  # 外側の var2 を更新
    
    local_func()
    print(f'{var1=}; {var2=}')
func()
ローカル関数 local_func() では var1 と var2 を更新していますが、var2 は nonlocal と宣言しているので、外側で定義された変数 var2 を更新します
これも関数定義でやってみましょう。
def func():
    var1 = 1
    
    def local_func():
        nonlocal var1  # 外側の var1 を更新
    
        def var1():    # 関数 var1 を定義
            print("Hi!")
    
    local_func()
    var1()
ローカル関数内で変数 var1 を nonlocal と宣言し、同じ名前で関数を定義しました。実行するとどうなるか、もうおわかりですね?
func()
local_func() では変数名 var1 を nonlocal と宣言していますから、var1 という名前の関数を作ると、当然外側の var1 が更新される、という寸法です。おっかないですね!
このページで紹介した global や nonlocal の使い方は、Pythonの名前の扱い方を紹介するためのサンプルです。普通のプログラムではまず使うことはありません。 Don't try this at home, Kids!
Copyright © 2020 Atsuo Ishimoto
Powered by miyadaiku