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.変数に入れまくってたが
インスタンス変数汚染しちゃうので変数のスコープは最小限にするようにコーディングしよう!