Python中如何生成支持自定义精度的可调用数字格式化函数
报错原因拆解
你遇到的这个报错,是没摸透Python str.format() 对嵌套占位符的解析规则导致的。
你原来的写法 '{:.{nf}g}'.format(nf=num_fig),在format解析器看来是这样的结构:
- 整个字符串里只有1个顶层占位符
{:.{nf}g},这个占位符没有指定字段名,默认要取调用时传入的位置0参数(也就是最终要格式化的数值)来填充 - 这个顶层占位符的格式说明部分
.{nf}g里,藏了一个嵌套占位符{nf},会在同一次format调用中被你传入的nf=num_fig替换值 - 你之前尝试在format里加
*args、**kwargs没能解决问题,本质是只要这个顶层的单大括号占位符存在,解析器就一定会要求传入对应索引的位置参数,不会因为你多传其他参数就跳过这个占位的填充要求。而你这次调用只传了用来替换nf的关键字参数,根本没传那个位置0的数值参数,自然抛出“位置参数索引超出范围”的错误。
修正方法
要让第一次设置精度的调用只替换{nf}部分、不去识别那个要接收数值的外层占位符,只需要把外层的大括号做转义就行——Python里用双写大括号{{}}实现转义,转义后的大括号不会被format当成占位符,只会在解析后输出为普通的单大括号文本。
适配你原有写法的修正代码
num_fig = 4 # 外层大括号双写转义,这步执行完会生成正常的格式串 '{:.4g}' num_formatter = '{{:.{nf}g}}'.format(nf=num_fig) # 把这个固定精度的格式串的format方法存下来当可调用的格式化函数 num_formatter = num_formatter.format # 之后直接传待格式化的数值就能正常工作 num_formatter(1.234567) # 返回结果为 '1.235'
更简洁的等价实现
完全可以省掉一次format调用,直接用f-string动态生成固定精度的格式串:
num_fig = 4 # f-string里{num_fig}会被动态替换,双写的{{}}输出为普通大括号,最终得到 '{:.4g}' num_formatter = f'{{:.{num_fig}g}}'.format num_formatter(1.234567) # 同样返回 '1.235'
内容的提问来源于stack exchange,提问作者Esteban
相关产品推荐
相关产品推荐

