python - Python 3.6 'f' 字符串的表达式与 `.format` 或 `.format_map` 不兼容
问题描述
我发现它.format_map
与Python 3.6字符串.format
不兼容,因为本机前缀允许复杂的表达式(例如切片和函数调用),但 do不允许复杂的表达式,例如:f
f
.format_map
>>> version = '1.13.8.10'
>>> f'example-{".".join(version.split(".")[:3])}'
'example-1.13.8'
>>> 'example-{".".join(version.split(".")[:3])}'.format_map(dict(version=version))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: '"'
'"'
>>> 'example-{".".join(version.split(".")[:3])}'.format(version=version)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: '"'
'"'
我真的希望能够通过配置文件公开 Python 字符串的全部功能,其中用户提供一个字符串,该字符串可能包含引用同一文件的f
非平凡段,并且可以选择执行一些基本数据操作,例如在 YAML 文件中{...}
我使用后处理键的子集,.format
以便它们可以引用同一配置文件中的变量。
这适用于简单的变量,例如{version}
YAML 文件是一个带有version
键的字典,我将 dict 作为参数传递给.format_map
,但抛出KeyError
更复杂的表达式(如上所示)。
必须有一种方法可以获得与f
字符串相同的功能......我以为.format_map
是......但它不提供复杂的表达式......
解决方案
你正在寻找eval
>>> def format_map_eval(string, mapping):
... return eval(f'f{string!r}', mapping)
...
>>> version = '1.13.8.10'
>>> some_config_string = 'example-{".".join(version.split(".")[:3])}'
>>> format_map_eval(some_config_string, dict(version=version))
'example-1.13.8'
这至少是明确的关于你提供这个。
f-strings 的关键特性是它们在格式化括号内评估任意表达式。如果您想要一个执行此操作的函数调用,那么您需要 eval。
现在我考虑一下,我不确定这在实现中是否安全或可移植,因为据我所知,无法保证repr
of 。str