pythonではその記述は、関数の中に関数を定義したとはみなされません。関数を定義する文のブロックの中に関数を定義する文を書いた、とみなされます。外側はそのまま評価されてグローバル名前空間にfunc
が登録されますが、内側は呼び出しのときまで評価されません。
要するに、a = "hoge"
と書いたのと同じで、実行時評価です。外側の関数の実行時まではfunc_inner
は存在しませんし、複数回呼べば別々のオブジェクトが生成されます。
python
1def func():
2 print("a")
3 def func_inner():
4 print("b")
python
1lst = []
2def func():
3 print("a")
4 def func_inner():
5 print("b")
6 lst.append(func_inner)
7
8func()
9func()
10func()
11print(lst)
12""" =>
13a
14a
15a
16[<function func.<locals>.func_inner at 0x7fa5cdb1f840>,
17 <function func.<locals>.func_inner at 0x7fa5cda87158>,
18 <function func.<locals>.func_inner at 0x7fa5cda871e0>]
19# 存在するメモリ番地が違う=呼び出し毎に別オブジェクトが生成されている
20"""
インスタンスの属性などとはまったく違った性質を持つと理解するべきです。self
は使えません(そもそも構文上受け付ける仕組みがないのだが)。原理的に「外側の関数を呼び出さないでアクセスする」方法はありません。
グローバル変数に代入するとか、return
で内側の関数を返して呼び出し側で束縛するとかすれば、「ある呼び出しの時に生成された内側の関数」を捕まえることは可能です。これをうまく利用したクロージャというテクニックもあります。しかし、積極的にそうする理由がなければ、関数内関数を外から呼ぶのは避けたほうが良いです(もっと言えば、関数内関数自体そうめったに必要になるものではない)。