1

I'm begginer in Python and I'm in front of a problem that I can't understand. I tried to just define a variable with a exec() and then just print it. And it's working well. BUT when I do the same code in a function, it's not working...

Example :

def fonct():
    possibilite = [0,1,2,3]
    testc = 0
    testl = 1
    commande = "proba"+str(testc+1)+str(testl)+" = possibilite"
    exec(commande)
    print(commande)
    print(proba11)

The same thing but not in a function has for result, that the command print(proba11) returns [0,1,2,3] so it works. But for the example I got this :

proba11 = possibilite
NameError: name 'proba11' is not defined

There is no stories about globals or locals, everything is local...

LeoZ
  • 13
  • 5
  • There is no variable named proba11, that's why you have this error. First, define proba11 if you want to print it – PCM Jun 08 '21 at 05:48
  • But when I do the same code, without defining proba11 but not in a function it's working. So I was thinking that it was ok to not define it, I will try, thank you. – LeoZ Jun 08 '21 at 05:53
  • `proba11 = possibilite` came because of this code `commande = "proba"+str(testc+1)+str(testl)+" = possibilite"`. It is just a string, not a variable – PCM Jun 08 '21 at 05:55
  • So you can't print it out – PCM Jun 08 '21 at 05:56
  • Ok, I tried, in the first lines of the function, I wrote proba11 = [0]. And the print(proba11) returns [0] and not [0,1,2,3].... So I think the exec() is not working as expected but I don't know why... I used it in other conditions and this is the only place I got problems.... – LeoZ Jun 08 '21 at 05:59
  • The line "proba11 = possibilite" pop out because of the line "print(commande)" to make sure the command is well wrote.... And then I execute commande. So it should define proba11... – LeoZ Jun 08 '21 at 06:01

1 Answers1

1

Updating the local variables with exec() in Python 3 is tricky due to the way local variables are stored. It used to work in Python 2.7 and earlier.

To workaround this, you need to

  • Pass an explicit locals dictionary to exec
  • Grab the newly defined variable from the updated locals dictionary

Like so:

def fonct():
    possibilite = [0, 1, 2, 3]
    testc = 0
    testl = 1
    varname = "proba" + str(testc + 1) + str(testl)
    commande = varname + " = possibilite"
    _locals = locals()
    exec(commande, globals(), _locals)
    proba11 = _locals[varname]
    print(proba11)

Which works as expected.

You can read more about it here:

rdas
  • 20,604
  • 6
  • 33
  • 46
  • Thank you very much ! It was just a trick a didn't know about, thank you for teaching me this ! – LeoZ Jun 08 '21 at 07:04