如果我有一个字符串
equation = "1+2+3+4"
如何将其更改为int并将答案等同?我在想这样的事情,但它会给出错误。
answer = (int)equation
print(answer)
等式可能包含+-*/
答案 0 :(得分:4)
如果我们想向全世界展示一个计算器,我会非常有兴趣看看一个破解者是否可以解决这个问题:
import string
def less_dangerous_eval(equation):
if not set(equation).intersection(string.ascii_letters + '{}[]_;\n'):
return eval(equation)
else:
print("illegal character")
return None
less_dangerous_eval('1*2/3^4+(5-6)')
返回:
3
我知道这可以通过给出错误的语法(使用try / except块修复)或者占用系统中所有内存的操作来解决(尝试/除了捕获这可能更加不确定),但我目前还没有意识到有人获得控制权。
答案 1 :(得分:3)
如果您准备接受风险,即您可能让恶意用户在您的计算机上运行他们喜欢的任何内容,您可以使用eval()
:
>>> equation = "1+2+3+4" >>> eval(equation) 10
如果您的代码只接受您控制的输入,那么这是最快捷,最简单的解决方案。如果您需要允许来自您以外的用户的常规输入,那么您需要寻找更具限制性的表达式评估程序。
<强>更新强>
感谢@roippi提醒我并指出上面的代码在调用代码的环境中执行。因此,将使用可用的局部变量和全局变量来计算表达式。像这样抑制:
eval(equation, {'__builtins__': None})
这不会使eval()
安全使用。它只是给它一个干净,空虚的环境来操作。敌对用户仍然可能会阻塞您的系统。
答案 2 :(得分:1)
如果您只有数字和加号,则此方法有效:
answer = sum(float(i) for i in equation.split('+'))
或者如果你知道它们只是整数
answer = sum(int(i) for i in equation.split('+'))
如果您希望能够评估更多,我建议您做好功课:
查找字符串模块(具有string.digits)
数学模块,其中包含您的操作
创建逻辑以按正确顺序执行操作
答案 3 :(得分:-2)
我建议您使用eval
并检查输入:
def evaluate(s):
import string
for i in s:
if i not in "+-*/ " + string.digits:
return False # input is not valid
return eval(s)
如前所述,eval
不安全,而且很难保证安全。我记得看到一篇非常好的博客文章解释了这个,有谁知道它是什么?但是ast.literal_eval
是安全的,但不允许使用__import__
等。我会强烈建议尽可能使用ast.literal_eval
代替eval
。不幸的是,在这种情况下,这是不可能的。但是,在不同的情况下,例如你只需要支持加法和乘法,你可以(而且应该)使用literal_eval
代替。
另一方面,如果这是家庭作业,您打算学习解析,那么我建议以不同的方式做这件事。我知道,如果我是老师,我会使用eval
回答“非常聪明,但这不会帮助你通过抽象语法树的测试。” (顺便提一下,如果你想“正确地”实现这一点,你应该看一下。)