回答編集履歴
5
追記
test
CHANGED
@@ -112,7 +112,7 @@
|
|
112
112
|
|
113
113
|
exec(f'from {module_name} import answer as _answer')
|
114
114
|
|
115
|
-
answer = locals()['_answer']
|
115
|
+
answer = locals()['_answer'] # eval('_answer') でも可
|
116
116
|
|
117
117
|
|
118
118
|
|
@@ -212,7 +212,7 @@
|
|
212
212
|
|
213
213
|
---
|
214
214
|
|
215
|
-
|
215
|
+
検討の末、判明したエラーの要因は次のとおりです。
|
216
216
|
|
217
217
|
- ローカルな名前空間を持つブロックで
|
218
218
|
|
@@ -222,7 +222,7 @@
|
|
222
222
|
|
223
223
|
|
224
224
|
|
225
|
-
こっちは
|
225
|
+
こっちは`NameError: name 'answer' is not defined`を吐きますが、 [Wandbox](https://wandbox.org/permlink/mLyOmRPV9qzmkOvv)
|
226
226
|
|
227
227
|
```Python
|
228
228
|
|
4
追記
test
CHANGED
@@ -208,7 +208,73 @@
|
|
208
208
|
|
209
209
|
|
210
210
|
|
211
|
-
|
211
|
+
原因
|
212
|
+
|
213
|
+
---
|
214
|
+
|
215
|
+
見当の末、判明したエラーの要因は次のとおりです。
|
216
|
+
|
217
|
+
- ローカルな名前空間を持つブロックで
|
218
|
+
|
219
|
+
- execに依って代入やそれに準ずる文を書き
|
220
|
+
|
221
|
+
- それ以降に同名の変数を宣言する場合
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
こっちはエラーを吐きますが、 [Wandbox](https://wandbox.org/permlink/mLyOmRPV9qzmkOvv)
|
226
|
+
|
227
|
+
```Python
|
228
|
+
|
229
|
+
def main():
|
230
|
+
|
231
|
+
exec('answer = 42')
|
232
|
+
|
233
|
+
answer = eval('answer')
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
return answer
|
238
|
+
|
239
|
+
|
240
|
+
|
241
|
+
print(
|
242
|
+
|
243
|
+
main()
|
244
|
+
|
245
|
+
)
|
246
|
+
|
247
|
+
```
|
248
|
+
|
249
|
+
|
250
|
+
|
251
|
+
こっちは吐かないです。[Wandbox](https://wandbox.org/permlink/tepA467Ua4rlrqCO)
|
252
|
+
|
253
|
+
```Python
|
254
|
+
|
255
|
+
def main():
|
256
|
+
|
257
|
+
exec('_answer = 42')
|
258
|
+
|
259
|
+
answer = eval('_answer')
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
return answer
|
264
|
+
|
265
|
+
|
266
|
+
|
267
|
+
print(
|
268
|
+
|
269
|
+
main()
|
270
|
+
|
271
|
+
)
|
272
|
+
|
273
|
+
```
|
274
|
+
|
275
|
+
|
276
|
+
|
277
|
+
最終的な結論
|
212
278
|
|
213
279
|
---
|
214
280
|
|
3
追記
test
CHANGED
@@ -96,4 +96,120 @@
|
|
96
96
|
|
97
97
|
|
98
98
|
|
99
|
+
グローバル空間の汚染を避ける
|
100
|
+
|
101
|
+
---
|
102
|
+
|
103
|
+
もう少し検討した結果、次のように書いた方がより正確であることに気付きました。
|
104
|
+
|
105
|
+
```Python
|
106
|
+
|
107
|
+
module_name = 'module'
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
def main(module_name):
|
112
|
+
|
113
|
+
exec(f'from {module_name} import answer as _answer')
|
114
|
+
|
115
|
+
answer = locals()['_answer']
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
print(answer)
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
main(module_name)
|
124
|
+
|
125
|
+
print(answer)
|
126
|
+
|
127
|
+
```
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
**実行結果** [Wandbox](https://wandbox.org/permlink/x8g174c7JiYRMvpb)
|
132
|
+
|
133
|
+
```plain
|
134
|
+
|
135
|
+
42
|
136
|
+
|
137
|
+
Traceback (most recent call last):
|
138
|
+
|
139
|
+
File "prog.py", line 10, in <module>
|
140
|
+
|
141
|
+
print(answer)
|
142
|
+
|
143
|
+
NameError: name 'answer' is not defined
|
144
|
+
|
145
|
+
```
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
スコープ外でちゃんとエラーになってくれるところが良さげです。
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
なお、`_answer`をいちいち経由しているのにも理由があります。
|
154
|
+
|
155
|
+
```Python
|
156
|
+
|
157
|
+
module_name = 'module'
|
158
|
+
|
159
|
+
|
160
|
+
|
161
|
+
def main(module_name):
|
162
|
+
|
163
|
+
exec(f'from {module_name} import answer')
|
164
|
+
|
165
|
+
answer = locals()['answer']
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
print(answer)
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
main(module_name)
|
174
|
+
|
175
|
+
# print(answer)
|
176
|
+
|
177
|
+
```
|
178
|
+
|
179
|
+
|
180
|
+
|
181
|
+
**実行結果** [Wandbox](https://wandbox.org/permlink/DjLeePr4lZxkrznq)
|
182
|
+
|
183
|
+
```plain
|
184
|
+
|
185
|
+
Traceback (most recent call last):
|
186
|
+
|
187
|
+
File "prog.py", line 9, in <module>
|
188
|
+
|
189
|
+
main(module_name)
|
190
|
+
|
191
|
+
File "prog.py", line 5, in main
|
192
|
+
|
193
|
+
answer = locals()['answer']
|
194
|
+
|
195
|
+
KeyError: 'answer'
|
196
|
+
|
197
|
+
```
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
Pythonインタプリタは関数内の代入を前もって舐めているので、
|
202
|
+
|
203
|
+
未初期化状態であるanswerをローカル辞書に登録することを避けるのでしょうね。
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
あくまで推測の域を出ませんが。
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
結論
|
212
|
+
|
213
|
+
---
|
214
|
+
|
99
215
|
やはりexecやevalを利用するのは最終手段ですね。
|
2
追記
test
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
おもしろい現象ですね。
|
2
|
+
|
3
|
+
このようなときは、ミニマムなコードで状況を再現し、原因を絞り込むのが常套手段です。
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
エラーの再現
|
8
|
+
|
9
|
+
---
|
2
10
|
|
3
11
|
次のようなコードで状況が再現しました。[Wandbox](https://wandbox.org/permlink/09T7CCwlKY57b9NT)
|
4
12
|
|
@@ -35,6 +43,10 @@
|
|
35
43
|
```
|
36
44
|
|
37
45
|
|
46
|
+
|
47
|
+
エラーの条件の検討と、解決
|
48
|
+
|
49
|
+
---
|
38
50
|
|
39
51
|
一方、main.pyを次のように書いたときには問題なく動作します。[Wandbox](https://wandbox.org/permlink/W1a5jFEkZtjS9jAz)
|
40
52
|
|
1
追記
test
CHANGED
@@ -81,3 +81,7 @@
|
|
81
81
|
main(module_name)
|
82
82
|
|
83
83
|
```
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
やはりexecやevalを利用するのは最終手段ですね。
|