Reputation: 27
When I have exec() in defined function it is not working ('NameError: name 'a' is not defined'):
def abc():
qwerty = "a = 2"
exec(qwerty)
abc()
print(a)
but, when I won't use def, it is working:
qwerty = "a = 2"
exec(qwerty)
print(a)
How can I "repair" it, or are there other similar solutions? (I can't execute this at start, I need to call that function in the middle of the program)
Upvotes: 1
Views: 3409
Reputation: 1
In my case, the Riven's comment helped me a lot:
loc = {}
def abc():
qwerty = "a = 2"
exec(qwerty, globals(), loc)
abc()
print(loc['a'])
In my case I had main script which called a second script. I needed to use the "c" variable within the second script. Therefore I used locals(),loc as arguments for exec().
loc = {}
a = 10
b = 5
def abc(a,b):
qwerty = "c = %d + %d"%(a,b)
exec(qwerty, locals(), loc)
c = loc['c']
d = c+2
print(d)
abc(a,b)
Upvotes: 0
Reputation: 1570
My answer is similar to @Cyrill's answer but with some subtle differences.
There are 3 ways to call the exec
function:
exec('a = 2')
. This will execute the statement in the current scope and thus create a local variable.exec('a = 2', globals())
. This will execute the statement in the suplied global namespace, which is also the current global namespace (returned by globals()
). This will mutate the global namespace.exec('a = 2', globals(), loc)
. This will execute the statement in the suplied local namespace (the third argument) using the suplied global namespace as the global namespace. This will mutate the local namespace.By using the second way we can execute code in the global namespace, so:
def abc():
qwerty = 'a = 2'
exec(qwerty, globals())
abc()
print(a) # outputs 2
Upvotes: 2
Reputation: 375
You are missing a parameter on exec()
function
variables used inside the exec function cannot be accessed as if they where declared globally
a workaround would be to pass 2 dictionaries in exec()
as such, i normally would do that like this..
loc = {}
def abc():
qwerty = "a = 2"
exec(qwerty, globals(), loc)
abc()
print(loc['a'])
which would then output 2
Upvotes: 1