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

如何实现接收参数名列表的make_function函数(规避eval用法)

替代eval的实现方案

你的eval实现确实存在调试不便、依赖函数名查找的问题,这里提供两种更安全可靠的替代方案:

方案一:闭包+自定义签名(推荐)

利用Python的闭包特性直接捕获inner_func对象,避免字符串形式的函数名查找,同时可以通过inspect模块自定义函数签名,让新函数的参数名符合要求:

from typing import List, Callable
import inspect

def make_function(arg_names: List[str], inner_func: Callable):
    def wrapper(*args, **kwargs):
        # 可选:添加参数校验,确保传入的参数与arg_names匹配
        # if len(args) > len(arg_names):
        #     raise TypeError(f"expected at most {len(arg_names)} positional arguments, got {len(args)}")
        # for kw in kwargs:
        #     if kw not in arg_names:
        #         raise TypeError(f"unexpected keyword argument: '{kw}'")
        return inner_func(*args, **kwargs) + 5
    
    # 自定义函数签名,让新函数的参数名显示为arg_names指定的内容
    params = [
        inspect.Parameter(name, inspect.Parameter.POSITIONAL_OR_KEYWORD)
        for name in arg_names
    ]
    wrapper.__signature__ = inspect.signature(wrapper).replace(parameters=params)
    return wrapper

优势:

  • 直接捕获inner_func对象,不会出现环境中找不到函数名的问题
  • 调试方便,可以直接在wrapper函数内添加断点或日志
  • 可选添加参数校验,增强鲁棒性

方案二:使用exec生成函数(适合需要严格参数签名的场景)

如果需要完全匹配指定参数名的函数签名(比如通过help()查看时显示准确参数),可以用exec动态生成函数,但需确保arg_names是可信的输入:

from typing import List, Callable
import functools

def make_function(arg_names: List[str], inner_func: Callable):
    args_str = ", ".join(arg_names)
    local_scope = {}
    # 生成函数定义的字符串并执行
    exec(f"def new_func({args_str}): return inner_func({args_str}) + 5", globals(), local_scope)
    new_func = local_scope["new_func"]
    # 将inner_func绑定到函数的闭包,避免后续名字查找问题
    functools.update_wrapper(new_func, inner_func)
    return new_func

注意事项:

  • 仅当arg_names来自可信来源时使用,避免注入风险
  • 生成的函数签名完全符合指定的参数名,行为与你原来的eval版本一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:30:37