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?
This is discussed on exec
s interaction with locals
. In the global
context (not in a function) there is no problem - exec
modifies global variables, and you see the result. In a function the execution context is the local function, but exec
cannot change the local context . 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. This is so stuff like expressions
and op
are available. Passing globals()
here is usually not useful unless you are actually using a global variable or some other function.
The third parameter is the locals exec
can use, and what will be populated. If you pass globals()
as the second parameter, then usually you want to pass local variables you intend to use here as well. Passing locals()
here will not modify your actual locals, so is usually more confusing.
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. 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. Note the function itself needs to be told to add a global ex
to its local context, hence two globals.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.