3

While trying to create a list comprehension and then run it I have become perplexed by the mercuriality of Python (3.5)'s exec() function.

I would expect all of the following examples to print out 10, but only (a) does. I know that the function takes the keyword arguments globals, locals but in all of these situations exec seems to have full access to foo. I have tried the code in the console as well as in a file but to no avail.

Why do (b), (c) and (d) not work as intended?

Is there a way of getting the altered variables after they have been exec'd within a function?

Does it involve the dreaded global variables?

(a)

def foo():
    return 10

exec("a = foo()")
print(a)    #Prints 10

(b)

def foo():
    return 10

def func():
    exec("b = foo()")
    print(b)    #NameError: name 'b' is not defined

func()

(c)

def foo():
    return 10

def func(bar):
    exec("c = bar()")
    print(c)    #NameError: name 'c' is not defined

func(foo)

(d)

def func():
    def foo():
        return 10
    exec("d = foo()")
    print(d)    #NameError: name 'd' is not defined

func()
  • Interestingly, (b), (c), and (d) actually do print "10" in python 2.7.10. – Myk Willis Nov 11 '16 at 19:17
  • @ekhumoro I had already seen that question but it does not explain this situation. I shall look over it again but you may have to explain further how this is an exact duplicate. – BladorthinTheGrey Nov 11 '16 at 19:30
  • @BladorthinTheGrey. Did you read the accepted answer? – ekhumoro Nov 11 '16 at 19:31
  • @ekhumoro Yes, the only specifically relevant bit was *you cannot change local variables in function scope in Python 3 using `exec`, even though it was possible in Python 2. Not even previously declared variables.* I want to know *why* this is the case and if there is an alternative. – BladorthinTheGrey Nov 11 '16 at 19:34
  • @BladorthinTheGrey. The accepted answer has a clear explanation and also gives a work-around. – ekhumoro Nov 11 '16 at 19:37
  • It's because `exec()` is a function in Python 3 whereas it was a statement in Python 2. Therefore the compiler can't use the presence of `exec` in a function to determine if local variable storage can be optimized. If local variable storage is optimized, local variables are accessed faster but can't be changed by code other than what's actually compiled in the function. – kindall Nov 11 '16 at 19:39
  • Ok, thank you, I understand it now. Apologies @ekhumoro. – BladorthinTheGrey Nov 11 '16 at 19:41

0 Answers0