buto > /dev/null

だいたい急に挑戦してゴールにたどり着かずに飽きる日々です

Python nonlocal変数

関数内からは外側の変数へ再代入ができない

メッセージを返すrtn_msg関数の中にはメッセージを生成するmake_msg関数がある まずは内側の関数から外側の変数msgを出力してみる

def rtn_msg():
    msg = 'Message:'

    def make_msg():
        print(msg)
        
    make_msg()

rtn_msg()

変数msgの値が出力される

Message:

次はmake_msg関数でメッセージを生成する

def rtn_msg():
    msg = 'Message:'

    def make_msg():
        # 値の再代入がNG
        msg += 'msg created!'
        # 外側の変数を参照はできる
        print(msg)
        
    make_msg()

rtn_msg()

変数msgが宣言されてないよ!って感じですかね?

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-26-93cfdcc0aa8e> in <module>
     10     make_msg()
     11 
---> 12 rtn_msg()

<ipython-input-26-93cfdcc0aa8e> in rtn_msg()
      8         print(msg)
      9 
---> 10     make_msg()
     11 
     12 rtn_msg()

<ipython-input-26-93cfdcc0aa8e> in make_msg()
      4     def make_msg():
      5         # 値の再代入がNG
----> 6         msg += 'msg created!'
      7         # 外側の変数を参照はできる
      8         print(msg)

UnboundLocalError: local variable 'msg' referenced before assignment

ここで nonlocal変数 を使う

def rtn_msg():
    msg = 'Message:'

    def make_msg():
        # nonlocal宣言
        nonlocal msg
        
        msg += 'msg created!'
        print(msg)
        
    make_msg()

rtn_msg()

内側の関数で変数msgをnonlocal宣言してあげるとメッセージが生成できる!

Message:msg created!

変数のスコープ意識しよう

これまで関数の外に引き継ぎたい値はself.変数に入れまくってたが インスタンス変数汚染しちゃうので変数のスコープは最小限にするようにコーディングしよう!