teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

訂正

2020/05/17 10:17

投稿

quickquip
quickquip

スコア11314

answer CHANGED
@@ -16,7 +16,7 @@
16
16
  ```
17
17
  では、関数内関数innerが**クロージャになっている**(=引数以外の変数を実行時の環境ではなく、自身が定義された環境(静的スコープ)において解決しているような**関数オブジェクト**である)わけです。
18
18
 
19
- もっと精確に言うと"ローカル変数inner束縛された関数オブジェクト"がクロージャになっているわけです。
19
+ もっと精確に言うと"ローカル変数inner束縛している関数オブジェクト"がクロージャになっているわけです。
20
20
 
21
21
  "その関数オブジェクトをreturnで返しているかどうか"は"その関数オブジェクトかクロージャかどうか"とは関係がない話です。
22
22
 

1

追記

2020/05/17 10:17

投稿

quickquip
quickquip

スコア11314

answer CHANGED
@@ -24,4 +24,67 @@
24
24
 
25
25
  > と入力することでクロージャーが実行できるとのことでした。このa()の()はなんなのですか?
26
26
 
27
- 関数オブジェクト**だから**`()`で実行できるというだけの話です。
27
+ 関数オブジェクト**だから**`()`で実行できるというだけの話です。
28
+
29
+ ----
30
+ (追記)
31
+
32
+ 質問者さんが理解していない事柄は
33
+ ```pytton
34
+ def hoge():
35
+ print('hoge')
36
+ ```
37
+ という文を実行した時に**何が起こるのか?** という点だと想像します。
38
+
39
+ def文を実行すると
40
+
41
+ - 与えられた引数リストとコードブロックから関数オブジェクトを生成する
42
+ - 名前空間で関数名を関数オブジェクトに束縛する
43
+
44
+ の2つのことが[起こります](https://docs.python.org/ja/3/reference/compound_stmts.html#function-definitions)。
45
+
46
+ 上記の2番目で起こることは(単純)[代入文](https://docs.python.org/ja/3/reference/simple_stmts.html#assignment-statements)と起こることと**何ら変わりありません**。
47
+
48
+ 言い換えると、`def hoge(): print('hoge')`を実行した時には、`hoge = 関数オブジェクト`を実行するのと同じことが起こっているのです。
49
+
50
+ その2つで**同じように**名前束縛が起こるのであれば、
51
+ ```python
52
+ def hoge():
53
+ print('hoge')
54
+
55
+ hoge()
56
+ ```
57
+ がまったく正しいPythonのコードで、`hoge()`で関数オブジェクトの呼び出しが起こることになんら不思議さを感じないと言うなら、それと**同じよう**に
58
+ ```python
59
+ hoge = 何か関数オブジェクト
60
+
61
+ hoge()
62
+ ```
63
+ も**まったく正しいPythonのコード**であって、そこに**不思議さを感じることがおかしい**のです。
64
+
65
+ ```python
66
+ def hoge():
67
+ print('HOGE')
68
+
69
+ print(hoge) # => <function hoge at 0xXXXXXXXX> (名前hogeを束縛しているオブジェクトが関数オブジェクトだと分かる)
70
+
71
+ a = hoge # 名前hogeを束縛しているオブジェクトで名前aを束縛する
72
+
73
+ hoge() # => HOGE (名前hogeを束縛しているオブジェクト=hoge関数を引数なしで呼び出す)
74
+ a() # => HOGE (名前aを束縛しているオブジェクト=hoge関数を引数なしで呼び出す)
75
+ ```
76
+ というコードを実行して考えてみてください。
77
+
78
+ 名前の束縛の項もぜひ読んでみましょう。
79
+ [https://docs.python.org/ja/3/reference/executionmodel.html#naming-and-binding](https://docs.python.org/ja/3/reference/executionmodel.html#naming-and-binding)
80
+
81
+ 以下の構造で、名前が束縛されます:
82
+
83
+ - 関数の仮引数 (formal parameter) 指定
84
+ - import 文
85
+ - クラスや関数の定義 (定義を行ったブロックで、クラスや関数名を束縛します)
86
+ - 代入が行われるときの代入対象の識別子
87
+ - for ループのヘッダ
88
+ - with 文や except 節の as の後ろ。
89
+
90
+ と書いてあります。(わかりやすいように箇条書きにしています)