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

如何在str.format或str.format_map中实现类似f-string的函数传参调用功能?

实现类似f-string的函数调用效果在str.format/format_map中

好问题!直接用str.format()的占位符写{fn("somearg")}这种函数调用是行不通的——因为str.format()的占位符语法只支持标识符、属性访问或者索引,不允许直接在占位符里写带参数的函数调用。不过我们有几种替代方案可以实现类似的效果,具体看你的需求场景:

方案1:提前调用函数,传递结果到format

这是最简单的方式,直接先执行函数调用,把结果作为参数传给format():

def my_function(arg):
    return f"processed value: {arg}"

# 先调用函数得到结果,再传入format
result = 'My string contains {processed_val}'.format(processed_val=my_function("somearg"))
print(result)
# 输出: My string contains processed value: somearg

这种方式适合函数参数固定、不需要在格式化时动态计算的场景,但如果你的模板字符串里已经写死了{fn("somearg")}这种格式,这个方案就不适用了,得看下面的方案。

方案2:自定义format_map解析函数调用

如果你的模板里已经是{fn("somearg")}这种格式,想要直接解析执行,可以通过自定义format_map的映射类来实现。核心思路是重写映射的__getitem__方法,当遇到类似函数调用的键时,解析并执行对应的函数:

import ast

def my_function(arg):
    return f"processed value: {arg}"

def another_func(num1, num2):
    return num1 + num2

class FunctionCallResolver(dict):
    def __getitem__(self, key):
        try:
            # 用AST解析占位符里的表达式,避免eval的安全风险
            expr_node = ast.parse(key, mode='eval').body
            if isinstance(expr_node, ast.Call):
                # 提取函数名
                func_name = expr_node.func.id
                # 提取位置参数(这里仅处理字符串/数字常量,复杂参数可扩展)
                args = [ast.literal_eval(arg) for arg in expr_node.args]
                # 提取关键字参数(可选扩展)
                kwargs = {kw.arg: ast.literal_eval(kw.value) for kw in expr_node.keywords}
                
                # 从字典中获取对应的函数
                target_func = super().__getitem__(func_name)
                # 调用函数并返回结果
                return target_func(*args, **kwargs)
        except (SyntaxError, AttributeError, KeyError):
            # 解析失败时,返回原始键或者抛出异常,根据需求调整
            return f"{{{key}}}"
    
    # 可选:处理get方法,避免format_map内部调用出错
    def get(self, key, default=None):
        try:
            return self[key]
        except KeyError:
            return default

# 使用示例
template1 = 'My string has {my_function("somearg")}'
template2 = 'Calculation result: {another_func(10, 20)}'

resolver = FunctionCallResolver({
    'my_function': my_function,
    'another_func': another_func
})

print(template1.format_map(resolver))
# 输出: My string has processed value: somearg
print(template2.format_map(resolver))
# 输出: Calculation result: 30

注意事项

  • 安全问题:虽然用ast.literal_eval比直接eval安全很多,但如果你的模板文件来自不可信来源,这种解析方式仍然有风险,需要谨慎使用。
  • 扩展性:上面的示例只处理了简单的位置参数和关键字参数,如果模板里有嵌套函数调用、变量引用等复杂情况,需要进一步扩展AST解析逻辑。
  • 批量处理文件:如果要处理包含这类模板的文件,你可以读取文件内容,按行或者按模板块拆分,然后用上面的FunctionCallResolver批量格式化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 12:52:33