python - 在变量中的python字符串上触发f-string解析
问题描述
这个问题来自handling jupyter magics
,但可以用更简单的方式表达。给定一个字符串s = "the key is {d['key']}"
和一个字典d = {'key': 'val'}
,我们要解析字符串。
旧方法是.format()
,这将引发错误 - 它不处理字典键。
"the key is {d['key']}".format(d=d) # ERROR
我认为唯一的方法是将字典转换为对象(在此处或此处进行解释)。
"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
and 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 最支持的)不太一样。
field_name ::= arg_name ("." attribute_name | "[" element_index "]")* [...] element_index ::= digit+ | index_string index_string ::= <any source character except "]"> +
和
表单的 [A]n 表达式
'[index]'
使用__getitem__()
语法是有限的,因为它将任何仅数字的字符串转换为整数,并且其他所有内容始终被解释为字符串(尽管您可以使用嵌套{}
占位符从另一个变量动态插入键值)。
如果您必须支持任意表达式,就像 f 字符串一样,并且您不从不受信任的来源获取模板字符串(这部分很重要),那么您可以解析出字段名称组件,然后使用该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)
现在报价被接受:
>>> s = "the key is {d['key']}"
>>> d = {'key': 'val'}
>>> evaluate_template_expressions(s)
'the key is val'
本质上,您可以对 执行相同的操作eval(f'f{s!r}', globals())
,但以上内容可能会让您更好地控制您可能想要支持的表达式。
推荐阅读
- macos - Mac App Store 之外的分发:请删除前缀“开发者 ID 应用程序:”
- spring-batch - 如何在多个实例中运行弹簧批处理而不创建重复项
- c# - 我在枚举我的 IEnumerable
n次? - sdk - ZKTECO - SDK - SDANDALONE - 在线注册
- mongodb - MongoDB 性能:Windows 2016 Server DC 与运行 Hyper-V Ubuntu 的同一台机器
- regex - 以 .* 开头的负前瞻
- react-native - react-native-camera 使我的应用程序崩溃
- vue.js - 单击 Bootstrap 折叠时,运行 Vue 函数以在 v-for 中获取数组数据
- c - 如何使用共享内存初始化未命名的信号量?
- html - 导航栏在菜单下拉菜单中向右移动