繁体   English   中英

如何使用ast.literal_eval评估f字符串

[英]How to evaluate f strings using ast.literal_eval

当尝试使用ast.literal_eval评估f字符串时, ast.literal_eval有关“格式错误的节点或字符串”的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'

我可以在f弦上使用ast.literal_eval吗? 如果是,我需要更改什么?

这是不可能的。 f字符串类似于以下1

map = {}
map.update(globals())
map.update(locals())
string.format(**map)

这实际上是一种戏剧性的轻描淡写-f字符串还支持其他类型的表达式,而不仅仅是名称查找或简单的事情,例如可以使用普通格式字符串进行的项目访问。 例如,它们支持任何其他有效的python表达式,包括函数调用,数学方程式等。

>>> expr = '"boom"'
>>> f'foo{eval(expr)}'
'fooboom'

通过使用__format__协议对f字符串进行求值,并使用普通的python对f字符串包含的表达式求值。 这意味着f字符串不能是文字。 这是一个表达式1 请注意,像任何任意表达式一样,它也不能安全地求值-因此,您可能甚至不希望ast.literal_eval “可评估”。

1在AST中,您将看到它是通过JoinedStrStrFormattedValue ast节点完成的。 其中,唯一可以视为文字的是Str

F字符串可以包含任意复杂的表达式。 一个简单的例子。

>>> a = 2; b=3; print(f'x{a**b}x')

x8x

它们既不是文字也不是文字,也不适用于literal_eval。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM