Python 3.2.1: exec('x = y()') sets a value in a toy example, but not in the full code

南笙酒味 提交于 2019-12-04 16:55:44

On Python 2.x, exec was a statement that changed variable lookup from LOAD_GLOBAL and LOAD_FAST to LOAD_NAME to every name you access on your function. That means it first search the local scope to see if can find the name to after check the global scope.

Now, on Python 3.x, the exec function cannot change this lookup and will never find the name you defined unless you add an argument with the scope you want the result to be evaluated.

exec(some_code, globals())

For that to work, you need to add global my_var inside the function to make sure the lookup will work.

Keep in mind these things will be inserted in the global namespace of your module...

BTW, why do you need exec or eval? Why can't you add real functions to your algorithm list?


As side note, I can see you don't change the algorithm var on your function, but if you do it'll introduce some undesired side effects because the default value you created is mutable and will be used on all function calls.

For safety, change it to None and create a new list if needed.

This doesn't attempt to answer the question, but rather expands the test-cases so the behavior can be seen better and preserved for reference. The results come from Python 3.2.2 on Windows. See JBernardo's answer for a "why" this behavior occurs.

From global scope ("toy example"):

>>> foo = "global-foo"
>>> exec('foo = "global-bar"')
>>> foo
'global-bar'

In a function (full context):

>>> def setIt():
        foo = "local-foo"
        exec('foo = "local-bar"')
        return foo

foo = "global-foo"
>>> setIt()
'local-foo'
>>> foo
'global-foo'

With specifying globals() (does not work for locals() at all):

>>> def setIt():
        foo = "local-foo"
        exec('foo = "local-bar"', globals())
        return foo

>>> foo = "global-foo"
>>> setIt()
'local-foo'
>>> foo
'local-bar'

Happy coding.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!