回答編集履歴

2

訂正

2020/05/17 10:17

投稿

quickquip
quickquip

スコア11042

test CHANGED
@@ -34,7 +34,7 @@
34
34
 
35
35
 
36
36
 
37
- もっと精確に言うと"ローカル変数inner束縛された関数オブジェクト"がクロージャになっているわけです。
37
+ もっと精確に言うと"ローカル変数inner束縛している関数オブジェクト"がクロージャになっているわけです。
38
38
 
39
39
 
40
40
 

1

追記

2020/05/17 10:17

投稿

quickquip
quickquip

スコア11042

test CHANGED
@@ -51,3 +51,129 @@
51
51
 
52
52
 
53
53
  関数オブジェクト**だから**`()`で実行できるというだけの話です。
54
+
55
+
56
+
57
+ ----
58
+
59
+ (追記)
60
+
61
+
62
+
63
+ 質問者さんが理解していない事柄は
64
+
65
+ ```pytton
66
+
67
+ def hoge():
68
+
69
+ print('hoge')
70
+
71
+ ```
72
+
73
+ という文を実行した時に**何が起こるのか?** という点だと想像します。
74
+
75
+
76
+
77
+ def文を実行すると
78
+
79
+
80
+
81
+ - 与えられた引数リストとコードブロックから関数オブジェクトを生成する
82
+
83
+ - 名前空間で関数名を関数オブジェクトに束縛する
84
+
85
+
86
+
87
+ の2つのことが[起こります](https://docs.python.org/ja/3/reference/compound_stmts.html#function-definitions)。
88
+
89
+
90
+
91
+ 上記の2番目で起こることは(単純)[代入文](https://docs.python.org/ja/3/reference/simple_stmts.html#assignment-statements)と起こることと**何ら変わりありません**。
92
+
93
+
94
+
95
+ 言い換えると、`def hoge(): print('hoge')`を実行した時には、`hoge = 関数オブジェクト`を実行するのと同じことが起こっているのです。
96
+
97
+
98
+
99
+ その2つで**同じように**名前束縛が起こるのであれば、
100
+
101
+ ```python
102
+
103
+ def hoge():
104
+
105
+ print('hoge')
106
+
107
+
108
+
109
+ hoge()
110
+
111
+ ```
112
+
113
+ がまったく正しいPythonのコードで、`hoge()`で関数オブジェクトの呼び出しが起こることになんら不思議さを感じないと言うなら、それと**同じよう**に
114
+
115
+ ```python
116
+
117
+ hoge = 何か関数オブジェクト
118
+
119
+
120
+
121
+ hoge()
122
+
123
+ ```
124
+
125
+ も**まったく正しいPythonのコード**であって、そこに**不思議さを感じることがおかしい**のです。
126
+
127
+
128
+
129
+ ```python
130
+
131
+ def hoge():
132
+
133
+ print('HOGE')
134
+
135
+
136
+
137
+ print(hoge) # => <function hoge at 0xXXXXXXXX> (名前hogeを束縛しているオブジェクトが関数オブジェクトだと分かる)
138
+
139
+
140
+
141
+ a = hoge # 名前hogeを束縛しているオブジェクトで名前aを束縛する
142
+
143
+
144
+
145
+ hoge() # => HOGE (名前hogeを束縛しているオブジェクト=hoge関数を引数なしで呼び出す)
146
+
147
+ a() # => HOGE (名前aを束縛しているオブジェクト=hoge関数を引数なしで呼び出す)
148
+
149
+ ```
150
+
151
+ というコードを実行して考えてみてください。
152
+
153
+
154
+
155
+ 名前の束縛の項もぜひ読んでみましょう。
156
+
157
+ [https://docs.python.org/ja/3/reference/executionmodel.html#naming-and-binding](https://docs.python.org/ja/3/reference/executionmodel.html#naming-and-binding)
158
+
159
+
160
+
161
+ 以下の構造で、名前が束縛されます:
162
+
163
+
164
+
165
+ - 関数の仮引数 (formal parameter) 指定
166
+
167
+ - import 文
168
+
169
+ - クラスや関数の定義 (定義を行ったブロックで、クラスや関数名を束縛します)
170
+
171
+ - 代入が行われるときの代入対象の識別子
172
+
173
+ - for ループのヘッダ
174
+
175
+ - with 文や except 節の as の後ろ。
176
+
177
+
178
+
179
+ と書いてあります。(わかりやすいように箇条書きにしています)