尝试使用ast.literal_eval
评估f字符串时,我得到ValueError
关于"格式错误的节点或字符串":
from ast import literal_eval
a = 10
literal_eval("f'test {a}'")
引发以下错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<...> in <module>()
3 a = 10
4
----> 5 literal_eval("f'test {a}'")
C:\...\lib\ast.py in literal_eval(node_or_string)
83 return left - right
84 raise ValueError('malformed node or string: ' + repr(node))
---> 85 return _convert(node_or_string)
86
87
C:\...\lib\ast.py in _convert(node)
82 else:
83 return left - right
---> 84 raise ValueError('malformed node or string: ' + repr(node))
85 return _convert(node_or_string)
86
ValueError: malformed node or string: <_ast.JoinedStr object at 0x000001F20CE718D0>
然而,它对原始字符串或二进制字符串没有问题:
>>> literal_eval("r'This'")
'This'
>>> literal_eval("b'This'")
b'This'
我可以让ast.literal_eval
处理f字符串吗?如果是的话,我需要改变什么?
答案 0 :(得分:2)
这是不可能的。 f-string类似于以下 1 :
map = {}
map.update(globals())
map.update(locals())
string.format(**map)
这实际上是一种戏剧性的轻描淡写 - f-strings还支持其他类型的表达式,这些表达式不仅仅是名称查找,也不支持像vanilla格式字符串可以获得的项目访问等简单事物。例如它们支持任何其他有效的python表达式,包括函数调用,数学方程等。
>>> expr = '"boom"'
>>> f'foo{eval(expr)}'
'fooboom'
使用__format__
协议评估f-string,并使用普通python评估它包含的表达式。这意味着f-string 不能为文字。它是 1 的表达式。请注意,与任意表达式一样,它无法安全地进行评估 - 因此您可能甚至不希望它是“可评估的”#34;无论如何,请ast.literal_eval
。
1 在AST中,您会看到它是通过JoinedStr
,Str
和FormattedValue
个ast节点完成的。其中,唯一可以被视为文字的是Str
。
答案 1 :(得分:0)
F字符串可以包含任意复杂的表达式。一个简单的例子。
>>> a = 2; b=3; print(f'x{a**b}x')
x8x
它们既不是文字,也不是文字,也不适合literal_eval。