如何使用 ast.literal_eval 计算 f 个字符串
How to evaluate f strings using ast.literal_eval
当尝试用 ast.literal_eval
评估 f 弦时,我得到一个 ValueError
关于 "malformed node or string":
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 弦上工作吗?如果是,我需要更改什么?
这是不可能的。 F 字符串类似于以下内容1 :
map = {}
map.update(globals())
map.update(locals())
string.format(**map)
这实际上是一种戏剧性的轻描淡写 -- f 字符串还支持其他类型的表达式,而不仅仅是名称查找或简单的东西,例如您可以使用普通格式字符串获得的项目访问。例如它们支持任何其他有效的 python 表达式,包括函数调用、数学方程式等。
>>> expr = '"boom"'
>>> f'foo{eval(expr)}'
'fooboom'
f 字符串使用 __format__
协议求值,它包含的表达式使用普通 python 求值。这意味着 f 字符串 不能 是文字。这是一个表达式1。请注意,与任何任意表达式一样,它不能被安全地计算——因此您可能甚至不希望它成为 "eval-able" by ast.literal_eval
无论如何。
1在 AST 中,您会看到它是通过 JoinedStr
、Str
和 FormattedValue
ast 节点。其中,唯一可以被视为文字的是 Str
.
F 字符串可以包含任意复杂的表达式。一个简单的例子。
>>> a = 2; b=3; print(f'x{a**b}x')
x8x
它们既不是文字也不是文字,不适合 literal_eval。
当尝试用 ast.literal_eval
评估 f 弦时,我得到一个 ValueError
关于 "malformed node or string":
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 弦上工作吗?如果是,我需要更改什么?
这是不可能的。 F 字符串类似于以下内容1 :
map = {}
map.update(globals())
map.update(locals())
string.format(**map)
这实际上是一种戏剧性的轻描淡写 -- f 字符串还支持其他类型的表达式,而不仅仅是名称查找或简单的东西,例如您可以使用普通格式字符串获得的项目访问。例如它们支持任何其他有效的 python 表达式,包括函数调用、数学方程式等。
>>> expr = '"boom"'
>>> f'foo{eval(expr)}'
'fooboom'
f 字符串使用 __format__
协议求值,它包含的表达式使用普通 python 求值。这意味着 f 字符串 不能 是文字。这是一个表达式1。请注意,与任何任意表达式一样,它不能被安全地计算——因此您可能甚至不希望它成为 "eval-able" by ast.literal_eval
无论如何。
1在 AST 中,您会看到它是通过 JoinedStr
、Str
和 FormattedValue
ast 节点。其中,唯一可以被视为文字的是 Str
.
F 字符串可以包含任意复杂的表达式。一个简单的例子。
>>> a = 2; b=3; print(f'x{a**b}x')
x8x
它们既不是文字也不是文字,不适合 literal_eval。