Предположим, у меня есть этот код:
import math
import traceback
def getValue(s,p,val):
d = {}
for k in range(len(p)):
d[p[k]]=val[k]
y = eval(s,d)
return str(round(y,3))
values = [5,3]
parameters = ['var1','var2']
s = 'var2*3/2 + math.log(100)-var1**2'
x = getValue(s,parameters,values)
print x
но я получаю только эту ошибку: NameError: имя «математика» не определено
Как я могу это исправить?
На данный момент я запускаю его в Wing IDE, Windows, и у меня есть это в первой строке: #!/usr/bin/env python
Самый простой способ — добавить символ math
к параметру globals
вызова eval
.
values = [5,3, math]
parameters = ['var1','var2','math']
Имейте в виду, что использование eval
с произвольным вводом опасно.
Что касается опасности eval, я хочу использовать ее только в динамических математических формулах с динамическими параметрами. Есть ли лучшие решения?
Убедитесь, что вы понимаете риски. Это нормально для доверенного ввода (например, в утилите только для личного использования). Его нельзя сделать безопасным для произвольного ввода. Существует много информации по этой теме, много здесь, на SO.
Второй параметр eval
, если он присутствует, должен ссылаться на глобальное пространство имен. Здесь вы явно назначили ему пустой словарь, поэтому у вас нет доступа к имени math
глобального пространства имен. Вместо этого вы можете назначить d
локальному пространству имен eval
:
import math
import traceback
def getValue(s,p,val):
d = {}
for k in range(len(p)):
d[p[k]]=val[k]
y = eval(s, globals(), d)
return str(round(y,3))
values = [5,3]
parameters = ['var1','var2']
s = 'var2*3/2 + math.log(100)-var1**2'
x = getValue(s,parameters,values)
print(x)
# -15.895
Как вы его запускаете? Если вы делаете это как исполняемый пакетный файл и работаете в Linux, вам следует добавить shebang для python (или python3)