gpt4 book ai didi

python - ValueError : malformed string when using ast. literal_eval

转载 作者:IT老高 更新时间:2023-10-28 20:50:54 35 4
gpt4 key购买 nike

众所周知,使用 eval() 存在潜在的安全风险,因此使用 ast.literal_eval(node_or_string)升职了

但是在 python 2.7 中,它在运行这个例子时返回 ValueError: malformed string:

>>> ast.literal_eval("4 + 9")

而在 python 3.3 中,此示例按预期工作:

>>> ast.literal_eval('4+9')
13

为什么它在 python 3 而不是 python 2 上运行?如何在不使用有风险的 eval() 函数的情况下在 python 2.7 中修复它?

最佳答案

这在 Python 2 上不起作用的原因在于它对 literal_eval 的实现。当右边的操作数是复数时,原始实现仅对加法和减法执行数字评估。这在语法上对于将复数表示为文字是必要的。

这个 was changed在 Python 3 中,它支持任何类型的有效数字表达式位于加法和减法的任一侧。但是,literal_eval 的使用仍然仅限于加减法。

这主要是因为 literal_eval 应该是一个将单个 constant 文字(表示为字符串)转换为 Python 对象的函数。有点像简单的内置类型的向后 repr。不包括实际的表达式求值,而且它适用于 Python 3 的事实只是其实现的一个很好的副作用。

为了评估实际表达式,无需使用 eval(我们不想这样做),我们可以编写自己的表达式评估算法,该算法在 AST 上运行。这非常简单,尤其是对于数字的简单算术运算(例如构建您自己的计算器等)。我们只需将字符串解析为 AST,然后通过查看不同的节点类型并应用正确的操作来评估结果树。

类似这样的:

import ast, operator

binOps = {
ast.Add: operator.add,
ast.Sub: operator.sub,
ast.Mult: operator.mul,
ast.Div: operator.div,
ast.Mod: operator.mod
}

def arithmeticEval (s):
node = ast.parse(s, mode='eval')

def _eval(node):
if isinstance(node, ast.Expression):
return _eval(node.body)
elif isinstance(node, ast.Str):
return node.s
elif isinstance(node, ast.Num):
return node.n
elif isinstance(node, ast.BinOp):
return binOps[type(node.op)](_eval(node.left), _eval(node.right))
else:
raise Exception('Unsupported type {}'.format(node))

return _eval(node.body)

如您所见,此实现非常简单。当然它还不支持更复杂的东西,比如求幂和一些一元节点,但添加它并不太难。而且效果很好:

>>> arithmeticEval('4+2')
6
>>> arithmeticEval('4*1+2*6/3')
8

你甚至可以在以后引入更复杂的东西(例如像 sin() 这样的函数调用)。

关于python - ValueError : malformed string when using ast. literal_eval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20748202/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com