You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Python旧式格式化字符串自动转换为f-strings?

你提到的为不同数量%s写多个正则的方式,确实不够通用,遇到复杂场景(比如格式化字符串里本身包含转义的%%、或者元组参数里有嵌套表达式)很容易踩坑。下面给你两种更靠谱的通用解决方案:

方案1:用成熟的自动化工具(推荐)

直接用专门的Python代码升级工具pyupgrade,它能自动识别旧式的%格式化语法,并在合适的场景下转换成f-string,支持任意数量的占位符,还能处理带格式说明符的情况(比如%d、%.2f)。

使用步骤:

  1. 安装工具:
pip install pyupgrade
  1. 处理你的代码文件:
pyupgrade --py36-plus your_script.py

这个命令会自动把符合条件的旧式格式化代码转换成f-string,而且能处理各种边缘情况,比自己写正则省心太多。

方案2:基于AST手动实现(适合自定义需求)

如果需要自定义转换逻辑,不要用正则——正则很难处理代码里的嵌套结构和复杂表达式。应该用Python的**抽象语法树(AST)**来解析代码,精准识别旧式格式化节点,再转换成f-string节点。

下面是一个简化版的实现示例:

import ast
import astunparse

class PercentToFStringTransformer(ast.NodeTransformer):
    def visit_Call(self, node):
        # 匹配 print("xxx %s xxx" % (arg1, arg2)) 这类调用结构
        if (isinstance(node.func, ast.Name) and node.func.id == 'print'
            and len(node.args) == 1
            and isinstance(node.args[0], ast.BinOp)
            and isinstance(node.args[0].op, ast.Mod)
            and isinstance(node.args[0].left, ast.Constant)
            and isinstance(node.args[0].right, (ast.Tuple, ast.Name, ast.Constant))):
            
            format_str = node.args[0].left.value
            # 处理单个参数的情况(比如 % arg 而不是 %(arg,))
            args = node.args[0].right.elts if isinstance(node.args[0].right, ast.Tuple) else [node.args[0].right]
            
            # 替换所有%s占位符
            parts = []
            arg_index = 0
            while '%s' in format_str:
                split_result = format_str.split('%s', 1)
                parts.append(split_result[0])
                # 把参数表达式转成字符串,嵌入f-string
                arg_code = astunparse.unparse(args[arg_index]).strip()
                parts.append(f'{{{arg_code}}}')
                format_str = split_result[1]
                arg_index += 1
            parts.append(format_str)
            
            # 构建新的f-string节点
            fstring_parts = []
            for part in parts:
                if part.startswith('{') and part.endswith('}'):
                    # 解析表达式节点
                    expr = ast.parse(part[1:-1]).body[0].value
                    fstring_parts.append(ast.FormattedValue(
                        value=expr,
                        conversion=-1,
                        format_spec=None
                    ))
                else:
                    fstring_parts.append(ast.Constant(value=part))
            
            node.args[0] = ast.JoinedStr(fstring_parts)
            return node
        
        return self.generic_visit(node)

# 测试示例
sample_code = '''
score = 10
total = 20
print("You: %s points. Me: %s points." % (score, total - score))
print("Single value test: %s" % (100,))
print("Escaped percent: %%s is a placeholder" % ("Hello",))
'''

# 解析、转换、输出代码
tree = ast.parse(sample_code)
transformer = PercentToFStringTransformer()
modified_tree = transformer.visit(tree)
print(astunparse.unparse(modified_tree).strip())

这个脚本会把示例中的旧式格式化代码自动转换成f-string,而且能处理单个参数、表达式参数等情况。如果需要支持更多格式说明符(比如%d转成{arg:d}),可以在转换逻辑里扩展判断。

内容的提问来源于stack exchange,提问作者Aristide

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:26:39