Назначение в exec в Python
Я пытаюсь построить калькулятор, используя PyQt5, и я получаю строку, которую мне нужно оценить, и назначаю ее переменной, чтобы я мог передать эту переменную виджетам в качестве ответа. До сих пор я могу оценить выражение, но не могу разобрать его. Как я могу это сделать? пока у меня есть следующий код:-
# 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 .....
Когда я пытаюсь запустить его без глобального, он работает без ошибок, но x остается 0, и если я запустил его так, я получаю эту ошибку:-
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
Я очень плохо знаком с Python, так что не могу понять, что происходит
2 ответа
global x = 5
не является допустимым кодом Python.
Если вы хотите назначить глобальную переменную x
, ты должен написать
global x
x = 5
Попробуйте изменить свой код как
global x
eqn1 = "{0} = {1}".format("x",eqn)
x = 0
exec(eqn1, globals())
Чтобы изменить глобальные переменные с помощью exec, вам нужно использовать функцию globals().
РЕДАКТИРОВАТЬ: Добавить функцию globals().
Хм, exec
а также eval
злые Когда вы используете их в необработанной строке, вы косвенно соглашаетесь выполнить почти любое выражение Python...
Но это не совсем то же самое использование: exec
предназначен для выполнения некоторого кода, в то время как eval
вернет значение. Вот правильный путь:
x = eval(eqn)
В любом случае, это неправильное использование глобальной переменной, поскольку она используется только для получения значения из вызова, поэтому правильный способ - иметь функцию, которая возвращает значение, следовательно, eval
вместо exec
,
Но помни: eval
это зло, поэтому никогда не используйте это в производственном коде.
На вопрос, почему это не работает, когда кто-то пытается изменить локальную переменную, это специально запрещено. Видеть это.