LOR3MI
LOR3MI

Reputation: 27

Python, exec() in defined function not working

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

Answers (3)

Gabriel Felix
Gabriel Felix

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

Roy Cohen
Roy Cohen

Reputation: 1570

My answer is similar to @Cyrill's answer but with some subtle differences.
There are 3 ways to call the exec function:

  1. With 1 argument, e.g. exec('a = 2'). This will execute the statement in the current scope and thus create a local variable.
  2. with 2 arguments, e.g. 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.
  3. with 3 arguments, e.g. 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

Riven
Riven

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

Related Questions