[英]why 'exec' is behaving different inside the function?
我的问题
我的解决方案:
import re
import math
a = input().replace("|","")
op = re.findall("[A-Z]+", a)[0]
a = list(map(float,re.split(r'P|S|M|D',a)))
expressions = {'P':'str(a[0]+a[1])','S':'str(a[0]-a[1])','M':'str(a[0]*a[1])','D':'str(a[0]/a[1])'}
exec('ex = eval(expressions[op])+"0"')
ex = ex[:ex.find(".")+3][::-1]
l = [6]
l.extend([6+3*x for x in range(1,(len(ex)-6)//2+1)])
if ex[-1]=="-":
l.pop()
for i in l:
ex = ex[:i] + "|" + ex[i:]
ex = ex[::-1]
ex = "0"+ex.strip("|") if ex.find("|")==1 else ex.strip("|")
print(ex)
问题:
如果我将此代码包装在 function 中,该 function 接受字符串输入并尝试返回我的ex
,代码显示错误并且没有任何改变。我的问题是,谁能解释为什么它单独工作完美并在包装在 function 中时抛出错误?
这在exec
与locals
的互动中进行了讨论。 在global
上下文中(不在函数中)没有问题 - exec
修改全局变量,您会看到结果。 在 function 中,执行上下文是本地 function,但exec
无法更改本地上下文。 通常的解决方法是传递一个本地上下文,您可以在其中看到更改:
local_context = {}
exec('ex = eval(expressions[op])+"0"', locals(), local_context)
ex = local_context['ex']
这里,第二个参数locals()
实际上是作为“全局变量”传递给 exec 的。 这就是expressions
和op
之类的东西可用。 除非您实际使用全局变量或其他一些 function,否则在此处传递globals()
通常没有用。
第三个参数是exec
可以使用的 locals,以及将填充的内容。 如果你传递globals()
作为第二个参数,那么通常你也想传递你打算在这里使用的局部变量。 在此处传递locals()
不会修改您的实际本地人,因此通常会更令人困惑。
注意使用
exec('global ex; ex = eval(expressions[op])+"0"')
global ex # Need this to make sure the function knows about the new global variable in its local context
将工作并创建一个具有正确内容的全局ex
变量。 这就是为什么exec
像您期望的那样使用 function 工作的原因,在全局上下文中修改当前上下文没有问题。 请注意 function 本身需要被告知将全局ex
添加到其本地上下文中,因此需要两个全局变量。
请注意,如果没有给出默认值,则局部变量为locals()
,全局变量为globals()
,如果仅给出全局变量,则局部变量也将等于该值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.