exec()
from inside a function gives a different output, even I pass all the parameter needed to that function. Consider this code:
def list_filter(expr,datalist,includelist) :
exec(expr)
print outlist
datalist=['try to kill me','black image']
includelist=['me']
expr="outlist = [i for i in datalist if all(j in i for j in includelist) ]"
exec(expr)
print outlist
list_filter(expr,datalist,includelist)
I have checked the similar case here : How does exec work with locals?
But this is a different error, where I'm using version 2.7.13 and I check under general condition, the exec()
normally has no error at all. I found this problem shows up when there's a 'nested loop' inside list comprehension statement, such as using all()
or any()
. As in this case , if I remove the if condition
from the list comprehension (make it to be expr = "outlist = [i for i in datalist ]"
) then I will get the correct output as usual.
Any idea why?
Almost always it's a bad idea to use exec
in this case you probably shouldn't use it at all.
But since you asked: It works correctly if you pass in the variables from the local scope:
def list_filter(expr, datalist, includelist):
exec(expr, locals())
print outlist
I'm not very familiar with the scope rules for exec
but I often found that you need to pass in the variables explicitly (especially if the exec
isn't in the global scope).
In your case you could even pass them in explicitly:
def list_filter(expr, datalist, includelist):
exec(expr, {'datalist': datalist, 'includelist': includelist})
print outlist
It's even stated in the documentation that you may need to pass the variables from the scope to exec
:
The built-in functions
globals()
andlocals()
return the current global and local dictionary, respectively, which may be useful to pass around for use byexec
.
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.