use*_*327 2 python eval function
我正在使用此代码来评估字符串中的数学表达式.它有效:
#!/usr/bin/env python
from __future__ import division
from math import *
expression = raw_input()
# Math functions
safe_list = ['math', 'factorial', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'hypot', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
# Create safe directory
safe_dict = dict([(key, locals().get(key, None)) for key in safe_list])
safe_dict['abs'] = abs
result = eval(expression, {"__builtins__": None}, safe_dict)
print result
Run Code Online (Sandbox Code Playgroud)
我把它包装在这样的函数中:
#!/usr/bin/env python
from __future__ import division
from math import *
def calculate(expression):
# Math functions
safe_list = ['math', 'factorial', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'hypot', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
# Create safe directory
safe_dict = dict([(key, locals().get(key, None)) for key in safe_list])
safe_dict['abs'] = abs
result = eval(expression, {"__builtins__": None}, safe_dict)
if isinstance(result, float) and result.is_integer():
result = int(result)
print result
expr = raw_input()
calculate(expr)
Run Code Online (Sandbox Code Playgroud)
它仍然适用于基本操作,但没有定义的功能safe_dict
正常工作.5**5
适用于这两个程序,但sin(pi)
使用第一个代码示例,它不适用于第二个代码.追溯是
Traceback (most recent call last):
File "stack.py", line 20, in <module>
calculate(expression)
File "stack.py", line 14, in calculate
result = eval(expression, {"__builtins__": None}, safe_dict)
File "<string>", line 1, in <module>
TypeError: 'NoneType' object is not callable
Run Code Online (Sandbox Code Playgroud)
它失败的原因是你从数学模块导入的函数不是函数内的局部变量; 他们是全球性的.因此,当您读取locals()并插入dict时,它会为每一个插入None.你会看到这个,如果你删除了get(key, None)
,只是locals()[key]
直接访问.
更好的方法是在数学模块上使用getattr.做import math
(不from math import *
)然后做safe_dict = dict((k, getattr(math, k)) for k in safe_list)
.