[Python] 07. globalとnonlocal


Study / Python    作成日付 : 2020/06/03 20:34:49   修正日付 : 2020/06/03 20:34:49

こんにちは。明月です。


この投稿はPythonでglobalとnonlocalに関する説明です。


以前の投稿でクロージャ(closure)に関して説明したことがあります。

link - [Python] 06. 関数(function) - インライン関数、callbak、ラムダ(lambda)そしてクロージャ


クロージャとはインライン関数で関数の外部から宣言したデータを持ち込むということです。

# 変数宣言
data = "hi!!"
# 関数生成
def example_function():
  # example_functionではdata変数を宣言してないが、外部のdataの変数を使える。
  print(data)
# 関数呼び出す。
example_function()


でも外部から宣言したデータを関数の内部で修正することはどうでしょう。

# 変数宣言
data = "hi!!"
# 関数生成
def example_function():
  # 外部dataの変数の値を修正する。
  data = "hello"
# 関数呼び出す。
example_function()
# コンソール出力
print(data)


example_function関数の内部でdataの値をhelloに変更しましたが、外部でコンソール出力するとデータが変更されないでした。

理由はexample_functionの中でdata="hello"したことは内部変数に認識して新しい変数を宣言したからです。


そうすると、仕様によってグローバル変数を関数の内部で変更する時もありますが、その時にはどうでしょう。

# 変数宣言
data = "hi!!"
# 関数生成
def example_function():
  # global宣言で外部変数を参照できるように設定
  global data
  # グローバル変数に格納
  data = "hello"
# 関数を呼び出す。
example_function()
# コンソール出力
print(data)


今回はdataの変数の値がちゃんと変更されました。


今回はインライン関数関数で使いましょう。

# 変数宣言
data = "global hi!!"
# 関数生成
def example_function():
  # 変数宣言
  data = "hi!!"
  # インライン関数生成
  def inline_function():
    # data変数はこの状況で一番近いステップのexample_functionのdata変数だ。
    print(data)
  # インライン関数を呼び出す。
  inline_function()
# 関数を呼び出す。
example_function()


上のグローバル変数でdata変数があり、example_functionの関数の中でもdata変数があります。

その状況でinline_function関数でdata変数を参照すれば、inline_function関数の一番近いステップの変数を参照します。

グローバル変数よりexample_functionの変数がもっと近いステップということです。


でも、使用によってグローバル変数を使いたいです。

# 変数宣言
data = "global hi!!"
# 関数生成
def example_function():
  # 変数宣言
  data = "hi!!"
  # インライン関数生成
  def inline_function():	
    # globalを宣言すればグローバル変数を参照することになる。
    global data
    # コンソール出力
    print(data)
  # インライン関数を呼び出す。
  inline_function()	
# 関数を呼び出す。
example_function()


そうすればinline_function中でもglobal関数を修正ができます。global dataをしてdata ="値"をいれば修正できます。

それなら、inline_function中でexample_functionのデータはどのように修正するでしょう?

単純にdata="値"を入れれば初めの例みたいにinline_function関数のデータに宣言されてしまいます。

# 変数宣言
data = "global hi!!"
# 関数生成
def example_function():
  # 変数宣言
  data = "hi!!"
  # インライン関数生成
  def inline_function():
    # nonlocalを使えば、example_functionのデータを参照できる。
    nonlocal data
    # 変数修正
    data = "hello"
  # インライン関数を呼び出す。
  inline_function()
  # コンソール出力
  print(data)
# 関数を呼び出す。
example_function()


globalはグローバル変数をnonlocalは一番近いステップの変数を参照することです。


そうすればインライン関数の中でインライン関数でグローバル変数ではないけど、一番トップにある変数を修正したいです。

# 変数宣言
data = "global hi!!"
# 関数生成
def example_function():	
  # ここの変数を修正したい。
  data = "hi!!"
  # インライン関数生成
  def inline_function():
    # 変数宣言  
    data = "third?"
    # インライン関数生成
    def inline2_function():	
      # nonlocalはinline_functionのdata変数を参照。
      nonlocal data
      # 変数修正
      data = "hello"
    # インライン関数を呼び出す。
    inline2_function()
  # インライン関数を呼び出す。
  inline_function()
  # コンソール出力  
  print(data)
# 関数を呼び出す。
example_function()


そこまでは参照ができないです。(何処まで参照したいのか?)

実は上みたいにソースを作成するとプログラム設計を考えなければならないです。可読性がすごく悪いですから。。。


ここまでPythonでglobalとnonlocalに関する説明でした。


ご不明なところや間違いところがあればコメントしてください。

最新投稿