此问题来自处理jupyter magics
,但可以用更简单的方式表达。给定一个字符串s = "the key is {d['key']}"
和一个字典d = {'key': 'val'}
,我们想解析该字符串。
旧方法为.format()
,这将引发错误-它不处理字典键。
"the key is {d['key']}".format(d=d) # ERROR
我认为唯一的解决方法是将字典转换为对象(解释为here或此处)。
"the key is {d.key}".format(obj(d))
但是Martijn很好地解释了,您可以简单地删除引号使它起作用:
"the key is {d[key]}".format(d=d)
仍然,新方法f'string'
确实以直观的python方式处理字典键:
f"the key is {d['key']}"
它还处理函数-.format
也无法处理。
f"this means {d['key'].lower()}"
尽管我们现在知道您可以使用.format
做到这一点,但我仍然想知道原来的问题:给定s
和d
,怎么办您是否强制f'string'
进行s
解析?我添加了另一个带有大括号内的函数的示例,该示例.format
也无法处理,f'string'
可以解决。
是否有可用的功能.fstring()
或方法? Python在内部使用什么?
答案 0 :(得分:4)
字符串格式可以处理大多数字符串字典键很好,但您需要删除引号:
"the key is {d[key]}".format(d=d)
演示:
>>> d = {'key': 'val'}
>>> "the key is {d[key]}".format(d=d)
'the key is val'
str.format()
语法与Python表达式语法(f字符串最支持的语法)不太一样。
来自Format String Syntax documentation:
field_name ::= arg_name ("." attribute_name | "[" element_index "]")* [...] element_index ::= digit+ | index_string index_string ::= <any source character except "]"> +
和
[A] n形式为
'[index]'
的表达式使用__getitem__()
进行索引查找
语法是有限的,因为它将所有仅数字的字符串转换为整数,并且其他所有内容始终被解释为字符串(尽管您可以使用嵌套的{}
占位符从中动态插入键值)另一个变量)。
如果您必须支持任意表达式,就像f字符串一样,并且不要从不受信任的来源获取模板字符串(这部分很重要),那么您可以先parse out the field name components,然后使用eval()
function评估值,然后再输出最终字符串:
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)
现在接受报价:
>>> s = "the key is {d['key']}"
>>> d = {'key': 'val'}
>>> evaluate_template_expressions(s)
'the key is val'
从本质上讲,您可以使用eval(f'f{s!r}', globals())
进行相同的操作,但是以上内容可能使您对想要支持的表达式有了更多的控制。
答案 1 :(得分:0)
[G]给出
s
和d
,您如何强制f'string'
的{{1}}解析?有可用的功能或方法吗?
这可以使用s
完成。 But beware eval
!
eval
>>> eval('f' + repr(s))
the key is val
用来转义任何引号,并用引号将repr
自身包裹起来。
如果您知道要格式化的变量(在这种情况下为s
),请选择Martijn's answer进行d
。由于str.format
的危险,上述解决方案应该是您的最后选择。