assignment within exec in python

4.5k Views Asked by At

I am trying to build calculator using PyQt5 and I get string which I need to evaluate and assign it to a variable so that I can Pass that variable to widgets as an answer . So far I can evaluate the expression but can't assing it . How can I do that ? so far I have following code:-

# this functions gets called when Enter is pressed
def etrp(self):
    eqn =  self.sender().text()                  #I get string like '23+4'
    eqn1 = "{0} = {1}".format("global x",eqn)    #I make it x = 23+4
    x = 0
    exec(eqn1)                                   # I get error here
    print(x)
    #some code .....

When I try to run it without global, it runs without error but x remains 0 and If I ran it like this I get this error:-

qt5ct: using qt5ct plugin
global x = 12+32
Traceback (most recent call last):
  File "/home/orayan/Development/Python/Calculator/calculator.py", line 11, in etrp
    exec(eqn1)
  File "<string>", line 1
    global x = 12+32
             ^
SyntaxError: invalid syntax
[1]    19185 abort (core dumped)  ./main.py

I am very new to python So can't figure out whats going on

3

There are 3 best solutions below

1
On BEST ANSWER
global x = 5

is not valid python code.

If you want to assign to a global variable x, you should write

global x
x = 5

Try changing your code as

global x
eqn1 = "{0} = {1}".format("x",eqn)
x = 0
exec(eqn1, globals())

To modify global variables with exec, you need to use globals() function.

EDIT: Add globals() function.

0
On

Hmm, exec and eval are evil. When you use them on a non sanitized string, you implicitely accept to execute almost any Python expression...

But that have not exactly same usages: exec is meant to execute some code, while eval will return a value. Here the correct way would be:

x = eval(eqn)

That is not a correct usage of a global variable anyway because it is only used to get a value from a call, so the correct way is to have the function to return the value, hence eval instead of exec.

But remember: eval is evil so never use that in production code.

2
On

On the question of why it doesn't work when one tries to modify a local variable, this is specifically forbidden. See this.