38
votes

I just started self teaching Python, and I need a little help with this script:

old_string = "didnt work"   
new_string = "worked"

def function():
    exec("old_string = new_string")     
    print(old_string) 

function()

I want to get it so old_string = "worked".

2
What's the point of this? Why do you want to use exec here? - Daniel Roseman
"I just started self teaching Python.." sounds like they're is just trying to wrap their head around a new language... - thebjorn

2 Answers

26
votes

You're almost there. You're trying to modify a global variable so you have to add the global statement:

old_string = "didn't work"
new_string = "worked"

def function():
    exec("global old_string; old_string = new_string")
    print(old_string)

function()

If you run the following version, you'll see what happened in your version:

old_string = "didn't work"
new_string = "worked"

def function():
    _locals = locals()
    exec("old_string = new_string", globals(), _locals)
    print(old_string)
    print(_locals)

function()

output:

didn't work
{'old_string': 'worked'}

The way you ran it, you ended up trying to modify the function's local variables in exec, which is basically undefined behavior. See the warning in the exec docs:

Note: The default locals act as described for function locals() below: modifications to the default locals dictionary should not be attempted. Pass an explicit locals dictionary if you need to see effects of the code on locals after function exec() returns.

and the related warning on locals():

Note: The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.

7
votes

As an alternative way of having exec update your global variables from inside a function is to pass globals() into it.

>>> def function(command):
...    exec(command, globals())
...
>>> x = 1
>>> function('x += 1')
>>> print(x)
2

Unlike locals(), updating the globals() dictionary is expected always to update the corresponding global variable, and vice versa.