0

Results running the code for python3:

------- input option 1 - exec code is executed --------
0 - for running inside function, 1 - for running in main programa: 1
option = 1
10

------- input option 0 - exec code not executed inside function ----
0 - for running inside function, 1 - for running in main programa: 0
option = 0
code inside execfunction => A = 10
Traceback (most recent call last):
  File "myexec.py", line 19, in <module>
    print(A)    
NameError: name 'A' is not defined
---------------------Code --------------------------

myexec.py

def execfunction(icode):
    print('code inside execfunction => %s' %(icode))
    exec(icode)

option = int(input("0 - for running inside function, 1 - for running in main programa: "))

print('option = %d' %(option))

code = 'A = 10'

if (option == 1):
    exec(code)
else:
    execfunction(code)  

print(A) 
Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
  • 5
    The code does not "fail". The variable has a different scope if the code is executed within the function. Move the print inside the function and you will see. – Mike Scotty May 31 '18 at 13:23
  • @MikeScotty Thats what I thought, that `A` was a local variable of the function `execfunction()` but I tried to `print(A)` and it still doesn't work, very weird. idk why. – Flaming_Dorito May 31 '18 at 13:27
  • I did like this, and still not working: – Marco Aurélio Falcão May 31 '18 at 13:29
  • #myexec.py def execfunction(icode): print('code inside execfunction => %s' %(icode)) exec(icode) print(A) option = int(input("0 - for running inside function, 1 - for running in main programa: ")) print('option = %d' %(option)) code = 'A = 10' if (option == 1): exec(code) print(A) else: execfunction(code) – Marco Aurélio Falcão May 31 '18 at 13:30
  • Sorry I dont konw how to upgrade my code in this tool – Marco Aurélio Falcão May 31 '18 at 13:31
  • Sorry, it seems I made an assumption w/o actually testing. Even though ``A`` is listed in ``locals()`` inside ``execfunction``, you cannot simply print it. @DavidZarebski is right with linking to [https://stackoverflow.com/a/15087355/4349415](https://stackoverflow.com/a/15087355/4349415) – Mike Scotty May 31 '18 at 13:36

3 Answers3

0

Is it because exec is a function in python 3 but a statement in python 2? Have a look at this discussion

zar3bski
  • 2,773
  • 7
  • 25
  • 58
  • No, that wouldn't matter in this case. That only matters when passing exec itself as a function. E.g., `map(exec, ["a = 1", "b+=2", "c=3"])` would work in Python 3, but fails in Python 2. His issue is with scoping. – Edward Minnix May 31 '18 at 13:42
  • Thanks for your attention! I have read the discussion. The workaround suggested is too complicated if one wants to keep his code easy to understand. – Marco Aurélio Falcão May 31 '18 at 13:55
  • Edward, Thanks, right, scoping. Maybe the compatibility with python3 should have been kept in this case. – Marco Aurélio Falcão May 31 '18 at 14:00
0

Python compiler will LOAD GLOBAL on encountering the print statement, where it fails as undefined variable 'A'. If you try to disassemble your code [import dis], you will get to see the execution of the backend process call.

A nice and well defined explanation is given in this Creating dynamically named variables in a function in python 3 / Understanding exec / eval / locals in python 3

Nishant Patel
  • 1,334
  • 14
  • 22
0

If you really want execfunction to execute the function in the global scope, you can do

def execfunction(code):
    exec(code, globals())

Then, this will make the calls to execfunction execute in the global scope, instead of only in the local scope of the function.

For reference: https://docs.python.org/3/library/functions.html#exec

Edward Minnix
  • 2,889
  • 1
  • 13
  • 26