我听说ast.literal_eval比eval()更安全,但在更改我的代码时,我收到'格式错误的字符串/节点'错误。
例如:
bar = False
incorrect = {"foo":bar}
correct = {"foo":"bar"}
ast.literal_eval(incorrect)
返回错误,但
ast.literal_eval(correct)
返回预期的{“foo”:“bar”}
为什么第一次评估没有返回{“foo”:False}
答案 0 :(得分:4)
因为它并不意味着那样做。来自文档:
安全地评估表达式节点或Unicode或Latin-1编码 包含Python表达式的字符串。提供的字符串或节点可以 只包含以下Python文字结构:字符串, 数字,元组,列表,dicts,布尔值和无。
ast.literal_eval
和eval
用于将python代码的字符串表示形式转换为...有效的python代码。
这不起作用:
>>> ast.literal_eval({"foo": "bar"})
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/usr/lib/python2.7/ast.py", line 80, in literal_eval
return _convert(node_or_string)
File "/usr/lib/python2.7/ast.py", line 79, in _convert
raise ValueError('malformed string')
ValueError: malformed string <-- Telltale right here.
那是因为你已经有一个有效的python结构,你试图评估它。
如果你在整个事情上加上引号,它会创建一个字典:
>>> ast.literal_eval('{"foo": "bar"}')
{'foo': 'bar'}
答案 1 :(得分:1)
来自documentation 在ast.literal_eval:
安全地评估表达式节点或包含Python表达式的Unicode或Latin-1编码字符串。提供的字符串或节点可能只包含以下Python文字结构:字符串,数字,元组,列表,dicts,布尔值和None。
这可用于安全地评估包含来自不受信任来源的Python表达式的字符串,而无需自己解析值。
bar
确实是False
,但不是 literal 。 literal_eval
看不到变量。它只适用于文字。