1

I am trying to make a class that is given a value, then executes a string in a list of strings based on the index given in order to change global variables. But I cannot figure out why the string that is executed cannot change the values of var1 and var0.

global var0, var1

class Change:
    def __init__(self, executed):
        self.executed = executed
    def changeGlobals(self):
        global var0, var1
        exec(self.executed)

var0 = 0
var1 = 1

executed = 'var0 = var0+1; var1 = var1+1;'

var = Change(executed)
var.changeGlobals()



# is supposed to print 'var0 is 1, var1 is 2'
print('var0 is '+str( var0 )+', var1 is '+str( var1 ))
# actually prints 'var0 is 0, var1 is 1'
Takistaks
  • 13
  • 3
  • 3
    Can we take a step back and talk about the broader context and _why_ you're trying to do this? – Paul H Oct 12 '20 at 15:25
  • 1
    Similar to [this](https://stackoverflow.com/questions/1463306/how-does-exec-work-with-locals) question, and may have the same answer (I don't use `exec`, so I can't say for sure). – Carcigenicate Oct 12 '20 at 15:27
  • 2
    your `global` staement in `changeGlobals` isn't going to affect the string that is being executed. It is assigning to a dict returned from `locals()`. In any case, almost certainly, this is not a good idea. Note also, `global var0, var1` is pointless at the top of the global scope. – juanpa.arrivillaga Oct 12 '20 at 15:27
  • So, you'd have to use a string like `Change("global var0; var0 = var0 + 1").changeGlobals()`. Alternatively, you could pass `globals()` as the second and third argument to `exec`, although that will make *everything* executed global. But again, this fundamentally seems like a bad design – juanpa.arrivillaga Oct 12 '20 at 15:32

1 Answers1

0

You are not changing values of the variable inside the changeGlobals() method, instead change like this:

global var0, var1

class Change:
    def __init__(self, executed):
        self.executed = executed
    def changeGlobals(self):
        global var0, var1
        var0 += 1
        var1 += 1
        exec(self.executed)

Another way is to change executed = 'var0 = var0+1; var1 = var1+1;' to executed = 'global var0, var1; var0 = var0+1; var1 = var1+1;' actually found that the global definition inside the passed string to exec works

Wasif
  • 14,755
  • 3
  • 14
  • 34
  • 2
    But then what's the point of `exec(self.executed)`? – wjandrea Oct 12 '20 at 15:30
  • 1
    @WasifHasan OK, but that's a different solution. I'm asking about the first solution. If it's not useful, you should just remove it from the answer. – wjandrea Oct 12 '20 at 15:39