简体   繁体   English

为什么'exec'在 function 内部表现不同?

[英]why 'exec' is behaving different inside the function?

My Question我的问题

问题

My solution:我的解决方案:

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)

The issue:问题:

If I wrap this code inside a function who take string input and try to return my ex the code shows error and nothing is changed.My question is, can anyone explain why this works perfect alone and throws error when wrapped inside a function?如果我将此代码包装在 function 中,该 function 接受字符串输入并尝试返回我的ex ,代码显示错误并且没有任何改变。我的问题是,谁能解释为什么它单独工作完美并在包装在 function 中时抛出错误?

This is discussed on exec s interaction with locals .这在execlocals的互动中进行了讨论。 In the global context (not in a function) there is no problem - exec modifies global variables, and you see the result.global上下文中(不在函数中)没有问题 - exec修改全局变量,您会看到结果。 In a function the execution context is the local function, but exec cannot change the local context .在 function 中,执行上下文是本地 function,但exec无法更改本地上下文 The usual work around is to pass a local context where you can see the changes:通常的解决方法是传递一个本地上下文,您可以在其中看到更改:

local_context = {}
exec('ex = eval(expressions[op])+"0"', locals(), local_context)
ex = local_context['ex']

Here, the second parameter locals() is in fact passed as a "globals" to exec.这里,第二个参数locals()实际上是作为“全局变量”传递给 exec 的。 This is so stuff like expressions and op are available.这就是expressionsop之类的东西可用。 Passing globals() here is usually not useful unless you are actually using a global variable or some other function.除非您实际使用全局变量或其他一些 function,否则在此处传递globals()通常没有用。

The third parameter is the locals exec can use, and what will be populated.第三个参数是exec可以使用的 locals,以及将填充的内容。 If you pass globals() as the second parameter, then usually you want to pass local variables you intend to use here as well.如果你传递globals()作为第二个参数,那么通常你也想传递你打算在这里使用的局部变量。 Passing locals() here will not modify your actual locals, so is usually more confusing.在此处传递locals()不会修改您的实际本地人,因此通常会更令人困惑。

Note using注意使用

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

will work and create a global ex variable with the correct content.将工作并创建一个具有正确内容的全局ex变量。 This is why exec works out of a function as you expect, in the global context there is no problem in modifying the current context.这就是为什么exec像您期望的那样使用 function 工作的原因,在全局上下文中修改当前上下文没有问题。 Note the function itself needs to be told to add a global ex to its local context, hence two globals.请注意 function 本身需要被告知将全局ex添加到其本地上下文中,因此需要两个全局变量。

Note the defaults is for the locals to be locals() and globals to be globals() if nothing is given, and if only the globals are given then the locals will equal that as well.请注意,如果没有给出默认值,则局部变量为locals() ,全局变量为globals() ,如果仅给出全局变量,则局部变量也将等于该值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM