はじめに
ネストされた関数を見ることは多いですが、私は初めの頃すんなりと理解出来なかったのでまとめます。
↓の記事で書いた**「関数を変数に格納して扱う方法」**の深掘りです。
関数を返す関数を実装する
さっそく関数を返す関数を作成します。
def add_func(value):
def func(value_2):
return value + value_2
return func
上記の関数**add_func()は内部で定義している関数func()**を返します。
実際に実行してみます。
def add_func(value):
def func(value_2):
return value + value_2
return func
add_1 = add_func(100)
print(add_1(1))
add_2 = add_func(1000)
print(add_2(1))
101
1001
上記の出力結果を見て「そりゃそうでしょ」とすんなり理解出来た人はもうこれから先を読まなくても大丈夫です。
C#やJavaに慣れている私は、初めてこのようなコードを見た時に一瞬頭の中が???となりました。。。
解説
まず下記の1行が実行されたときにどうなるか見ていきたいと思います。
add_1 = add_func(100)
変数add_1には関数add_func()内でreturnしている関数func()が格納されます。
関数が格納されているので変数add_1のタイプを出力してみるとfunctionとなっています。
add_1 = add_func(100)
print(type(add_1))
<class 'function'>
ここでポイントになるのが、変数add_1には**「展開された後の関数func()が格納される」**ということです。
add_func(100)
として引数valueに100を格納したことで、func()内で使用しているvalueは100に確定します。
※下記、展開後1の状態
def add_func(value):
def func(value_2):
return value + value_2
return func
add_1 = add_func(100)
# 展開後1
def add_func(100):
def func(value_2):
return 100 + value_2
return func
そのままreturnとしてvalueが100と決まっているfunc()が返却されます。
※下記、展開後2の状態
# 展開後2
def func(value_2):
return 100 + value_2
return func
つまり
def add_func(value):
def func(value_2):
return value + value_2
return func
add_1 = add_func(100)
print(add_1(1))
def func(value_2):
return 100 + value_2
return func
print(func(1))
上記のA'はAと同じ意味となります。
以上