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

如何使用LibCST实现将单引号f-string转为三引号且正确处理嵌套场景的转换器

如何使用LibCST实现将单引号f-string转为三引号且正确处理嵌套场景的转换器

我来帮你搞定这个LibCST转换器的问题!你想要的效果是把外层的单/双引号f-string替换成对应的三引号,同时让内部嵌套的f-string保持原样对吧?之前你尝试的call_if_not_inside匹配逻辑可能没精准命中嵌套场景,咱们来调整一下实现思路。

核心思路

关键要准确区分外层非嵌套的f-string和内层嵌套的f-string:

  • 外层f-string:没有被包含在另一个f-string的表达式部分里,需要把单/双引号改成三引号
  • 内层嵌套f-string:作为其他f-string中{}里的表达式内容,要保持原引号不变

完整实现代码

import libcst as cst
import libcst.matchers as m

class FormattedStringQuoteTransformer(cst.MatcherDecoratableTransformer):
    @m.call_if_not_inside(
        # 匹配"当前节点处于另一个f-string的表达式内容中"的场景,这类节点不处理
        m.FormattedString(
            parts=m.Contains(
                m.FormattedStringExpression(
                    expression=m.MatchIfTrue(lambda node: isinstance(node, cst.FormattedString))
                )
            )
        )
    )
    @m.leave(m.FormattedString(quote=m.MatchIfTrue(lambda q: q in ("'", '"'))))
    def convert_single_quote_to_triple(self, original_node: cst.FormattedString, updated_node: cst.FormattedString) -> cst.FormattedString:
        # 根据原引号类型替换为对应的三引号
        new_quote = "'''" if original_node.quote == "'" else '"""'
        return updated_node.with_changes(quote=new_quote)

代码解释

  1. 嵌套场景排除逻辑:
    call_if_not_inside里的匹配器会检查当前f-string是否被包含在另一个f-string的parts中,且这个parts里存在一个FormattedStringExpression(也就是{}里的内容),而该表达式本身又是一个FormattedString——这样就精准定位了嵌套的f-string,这类节点会被跳过处理。

  2. 引号转换逻辑:
    leave装饰器专门匹配使用单引号或双引号的f-string,处理函数里会根据原引号的类型,替换成对应的三引号(单引号转''',双引号转""")。

测试效果

拿你给出的例子来测试:
原代码:

f"\
Hello {developer_name}
My name is {_get_machine(f'{self.prop_a}, {self.prop_b}')}
"

经过转换器处理后,会得到:

f"""\
Hello {developer_name}
My name is {_get_machine(f'{self.prop_a}, {self.prop_b}')}
"""

完美实现了外层转三引号、内层嵌套f-string保持原样的需求~

额外注意点

  • 这个逻辑支持多层嵌套的f-string,只有最外层的非嵌套f-string会被转换
  • 如果原f-string已经是三引号,不会被修改,避免重复转换

备注:内容来源于stack exchange,提问作者Maxim Kirilov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 12:43:05