Why does this code raise NameError
?:
def func():
exec("my_var = 42")
print(my_var)
func()
There are many related questions, but I have not found a clear answer as to WHY. I don't want a workaround.
Also, I have noticed that the code works when I run:
exec("my_var = 42", globals(), globals())
But not really sure why.
The documentation for exec() states: "...if the optional parts are omitted [second and third arguments], the code is executed in the current scope.". The current scope is the func() function. Why can't I access my_var from this same scope?
CodePudding user response:
The parser/compiler doesn't take the argument to exec()
into account (since it could be a variable). So when it parses the function it doesn't see the assignment to my_var
, so it treats it as a global variable. But the assignment in exec()
will create a local variable. So the variable that was assigned is not the same one that it tries to print.
CodePudding user response:
To understand what's happening with this code, you need to try the following situation:
my_var = None
def func():
exec("my_var = 42")
print(my_var)
func()
The output is None
because the variable is declared as a global variable, outside the function. But if you declare it inside and execute exec("my_var = 42", globals(), globals())
it becomes automatically a global variable that you can use outside your function, as you can see when running globals()
:
def func():
exec("my_var = 42", globals(), globals())
print(my_var)
func()
print(my_var, globals())
Output:
42 {'my_var': 42 ......}