Roe*_*ant 1 python string string-formatting python-3.x f-string
这个问题来自处理jupyter magics
,但可以用更简单的方式表达。给定一个字符串s = "the key is {d['key']}"
和一个字典d = {'key': 'val'}
,我们想解析这个字符串。
旧方法是.format()
,这会引发错误 - 它不处理字典键。
"the key is {d['key']}".format(d=d) # ERROR
Run Code Online (Sandbox Code Playgroud)
我认为唯一的方法是将字典转换为对象(在此处或此处解释)。
"the key is {d.key}".format(obj(d))
Run Code Online (Sandbox Code Playgroud)
但是Martijn很好地解释了,您可以简单地省略引号以使其正常工作:
"the key is {d[key]}".format(d=d)
Run Code Online (Sandbox Code Playgroud)
新方法仍然f'string'
以直观的 Python 方式处理字典键:
f"the key is {d['key']}"
Run Code Online (Sandbox Code Playgroud)
它还处理功能——某些东西.format
也无法处理。
f"this means {d['key'].lower()}"
Run Code Online (Sandbox Code Playgroud)
虽然我们现在知道你可以用来做.format
,但我仍然想知道最初的问题:给定s
和d
,你如何强制f'string'
解析s
?我在大括号内添加了另一个带有函数的示例,该示例.format
也无法处理并且f'string'
能够解决。
是否有一些功能.fstring()
或方法可用?Python 内部使用什么?
字符串格式可以很好地处理大多数字符串字典键,但您需要删除引号:
"the key is {d[key]}".format(d=d)
Run Code Online (Sandbox Code Playgroud)
演示:
>>> d = {'key': 'val'}
>>> "the key is {d[key]}".format(d=d)
'the key is val'
Run Code Online (Sandbox Code Playgroud)
str.format()
语法与 Python 表达式语法(这是 f-strings 主要支持的)不太一样。
Run Code Online (Sandbox Code Playgroud)field_name ::= arg_name ("." attribute_name | "[" element_index "]")* [...] element_index ::= digit+ | index_string index_string ::= <any source character except "]"> +
和
表单的 [A]n 表达式
'[index]'
使用__getitem__()
语法是有限的,因为它会将任何纯数字字符串转换为整数,而其他所有内容始终被解释为字符串(尽管您可以使用嵌套{}
占位符从另一个变量动态插入键值)。
如果您必须支持任意表达式,就像 f-strings 一样,并且您不从不受信任的来源获取模板字符串(这部分很重要),那么您可以解析字段名称组件,然后使用该eval()
函数来评估值在输出最终字符串之前:
from string import Formatter
_conversions = {'a': ascii, 'r': repr, 's': str}
def evaluate_template_expressions(template, globals_=None):
if globals_ is None:
globals_ = globals()
result = []
parts = Formatter().parse(template)
for literal_text, field_name, format_spec, conversion in parts:
if literal_text:
result.append(literal_text)
if not field_name:
continue
value = eval(field_name, globals_)
if conversion:
value = _conversions[conversion](value)
if format_spec:
value = format(value, format_spec)
result.append(value)
return ''.join(result)
Run Code Online (Sandbox Code Playgroud)
现在接受报价:
>>> s = "the key is {d['key']}"
>>> d = {'key': 'val'}
>>> evaluate_template_expressions(s)
'the key is val'
Run Code Online (Sandbox Code Playgroud)
本质上,您可以使用 做同样的事情eval(f'f{s!r}', globals())
,但上面的内容可能会让您更好地控制您可能想要支持的表达式。