1

I have two blocks of python code, one works, and the other doesn't.


Working block:

env = {'user':'xyz'}
for key, value in env.items():
    exec("{} = value".format(key))

print(user)

output:

xyz


The block, which doesn't work:

def test():
    env = {'user':'xyz'}
    for key, value in env.items():
        exec("{} = value".format(key))

    print(user)

test()

output:

NameError: name 'user' is not defined


The only difference I see is that the first block is being called in the global scope.

Could you please explain?

Many thanks!

PS: With all due respect, I know, I should avoid using exec() but what if I want to.

Anil Bisht
  • 55
  • 1
  • 6
  • 1
    The global scope is just a dictionary, and can be modified by `exec` or various other means. But the local scope of a function is carved in stone at the time the function was compiled (all references get turned into an index into an array), there's no way to add names at runtime. – jasonharper Feb 08 '21 at 02:35
  • @jasonharper thanks, if I print locals(), it confirms the presence of this variable:{'env': {'user': 'xyz'}, 'key': 'user', 'value': 'xyz', 'user': 'xyz'}. What are your thoughts? – Anil Bisht Feb 08 '21 at 02:40
  • As said above, it shows in locals() and also in the debugger, it shows up as a variable. Why does that happen? https://i.imgur.com/Ry1xoDX.png When I try to access it on the next line, it raises exception. – vighnesh153 Feb 08 '21 at 02:42
  • if you really need to use `exec()` then use it - but I would rather keep it as dictionary `env['user'] = ...` because it can be more useful then creating variables `user = ...` – furas Feb 08 '21 at 03:33
  • @furas the whole point of discussion is that I am not able to use exec() – Anil Bisht Feb 08 '21 at 04:14

1 Answers1

1

I recommend you reading this

You have to use locals() or exec or eval to access variables defined by exec in a function in Python3.

def test():
    env = {'user': 'xyz'}
    for key, value in env.items():
        exec("{} = value".format(key))
    exec("print(user)")
    print(locals()['user'])
    print(eval("user"))
 
test()

It should be noted that, if you attempt to store value returned from eval. You will get NameError.

def test():
    env = {'user': 'xyz'}
    for key, value in env.items():
        exec("{} = value".format(key))
    user = eval("user")
    print(user)

test()

returns

Traceback (most recent call last):
  File "D:/Git/sscgc/test.py", line 8, in <module>
    test()
  File "D:/Git/sscgc/test.py", line 5, in test
    user = eval("user")
  File "<string>", line 1, in <module>
NameError: name 'user' is not defined
david190810
  • 11
  • 1
  • 5