format(**locals())与f-string在字典变量键取值场景的差异及解法
问题原因
你用format(**locals())报错的核心原因是:Python的format解析占位符时,会把{cur_cols_dct[col]}里的col当成字符串字面量,而非变量。它会尝试从cur_cols_dct中取键为'col'的值,但你的字典里根本没有这个键,所以抛出KeyError。
简单说,format支持索引,但只能用字面量索引(比如"{cur_cols_dct['art_id']}"),没法把col这种变量解析成索引值。
替代方案
方案1:提前计算值,用简单占位符(最安全推荐)
修改模板为简单占位符,先算出要插入的内容,再调用format:
templ = "COMMENT IS '{comment}'" cur_cols_dct = {'art_id':'ID of article'} col = 'art_id' # 提前计算目标值 comment = cur_cols_dct[col] print(templ.format(**locals()))
输出:
COMMENT IS 'ID of article'
方案2:动态生成f-string(不修改原模板)
如果不想改动模板结构,可以用eval延迟解析f-string,让模板在变量定义完成后再被处理:
templ = "COMMENT IS '{cur_cols_dct[col]}'" cur_cols_dct = {'art_id':'ID of article'} col = 'art_id' # 把模板转成f-string字面量再执行 result = eval(f"f{templ!r}") print(result)
输出同样符合预期。注意:如果模板来自不可信的外部输入,别用这个方法,避免代码注入风险。
方案3:自定义Formatter(进阶复用场景)
如果需要频繁处理这类带变量索引的模板,可以继承string.Formatter重写解析逻辑:
from string import Formatter class VarIndexFormatter(Formatter): def get_value(self, key, args, kwargs): # 识别并解析带变量索引的表达式 if isinstance(key, str) and '[' in key: return eval(key, kwargs) return super().get_value(key, args, kwargs) templ = "COMMENT IS '{cur_cols_dct[col]}'" cur_cols_dct = {'art_id':'ID of article'} col = 'art_id' formatter = VarIndexFormatter() print(formatter.format(templ, **locals()))
这个方法适合需要复用复杂模板逻辑的场景,但同样要注意eval的安全限制。
内容的提问来源于stack exchange,提问作者Valiot
相关产品推荐
相关产品推荐

