在变量中的 python 字符串上触发 f 字符串解析
Trigger f-string parse on python string in variable
这个问题来自处理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 内部使用什么?
字符串格式可以处理大多数字符串字典键很好,但您需要删除引号:
"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-strings 主要支持的语法)不太一样。
来自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 expression of the form '[index]'
does an index lookup using __getitem__()
语法是有限的,因为它会将任何纯数字字符串转换为整数,而其他所有内容始终被解释为字符串(尽管您可以使用嵌套的 {}
占位符动态插入键来自另一个变量的值)。
如果您必须支持任意表达式,就像 f-strings 一样,并且您不要从不受信任的来源获取模板字符串 (这部分很重要),然后您可以 parse out the field name components and then use the 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())
执行相同的操作,但以上内容可能会让您更好地控制您可能想要支持的表达式。
[G]iven s
and d
, how do you force a f'string'
parse of s
? Is there some function or method available?
这可以使用 eval
来完成...。 But beware eval
!
>>> eval('f' + repr(s))
the key is val
repr
用于转义任何引号并用引号将 s
自身包裹起来。
如果您知道要格式化哪些变量(在本例中为 d
),请选择 而不是 str.format
。由于 eval
.
的危险,上述解决方案应该是你最后的选择
这个问题来自处理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 内部使用什么?
字符串格式可以处理大多数字符串字典键很好,但您需要删除引号:
"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-strings 主要支持的语法)不太一样。
来自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 expression of the form
'[index]'
does an index lookup using__getitem__()
语法是有限的,因为它会将任何纯数字字符串转换为整数,而其他所有内容始终被解释为字符串(尽管您可以使用嵌套的 {}
占位符动态插入键来自另一个变量的值)。
如果您必须支持任意表达式,就像 f-strings 一样,并且您不要从不受信任的来源获取模板字符串 (这部分很重要),然后您可以 parse out the field name components and then use the 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())
执行相同的操作,但以上内容可能会让您更好地控制您可能想要支持的表达式。
[G]iven
s
andd
, how do you force af'string'
parse ofs
? Is there some function or method available?
这可以使用 eval
来完成...。 But beware eval
!
>>> eval('f' + repr(s))
the key is val
repr
用于转义任何引号并用引号将 s
自身包裹起来。
如果您知道要格式化哪些变量(在本例中为 d
),请选择 str.format
。由于 eval
.