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

如何编写可作为模块使用的Python函数合并函数?

解决函数合并后无法跨模块调用的问题

问题根源

你之前用inspect+eval的实现无法跨模块调用,核心原因是eval生成的函数会绑定到执行eval的模块命名空间,其__module__属性与原函数f、g的模块不一致,跨模块导入后会出现找不到函数引用的问题。

替代实现(支持跨模块调用)

无需依赖eval,直接通过inspect获取参数签名,结合包装函数与元数据修正,就能实现符合要求的函数合并:

import inspect
import functools

def merge_functions(f, g):
    # 获取原函数的参数签名(假设f和g参数兼容,需校验可自行添加逻辑)
    sig = inspect.signature(f)
    params = list(sig.parameters.values())

    @functools.wraps(f)
    def merged_func(*args, **kwargs):
        # 绑定参数并校验合法性
        bound_args = sig.bind(*args, **kwargs)
        bound_args.apply_defaults()
        # 依次调用f和g
        f(*bound_args.args, **bound_args.kwargs)
        g(*bound_args.args, **bound_args.kwargs)
    
    # 显式设置参数签名,保留原函数的参数名称与结构
    merged_func.__signature__ = sig
    # 修正模块属性,确保跨模块导入时的命名空间正确
    merged_func.__module__ = f.__module__ if hasattr(f, '__module__') else __name__
    
    return merged_func

关键细节说明

  • 参数签名保留:通过inspect.signature获取原函数的参数结构,再给合并后的函数设置__signature__属性,保证调用时的参数提示与原函数一致。
  • 模块属性修正:手动设置__module__为原函数f的模块,避免跨模块导入时出现函数引用失效的问题。
  • 兼容性处理:functools.wraps会自动继承原函数的__name__、__doc__等元数据,让合并后的函数更贴近原生定义。

扩展:处理f和g参数不一致的情况

如果f和g的参数签名不同,可通过合并两者的参数列表实现兼容:

def merge_functions(f, g):
    sig_f = inspect.signature(f)
    sig_g = inspect.signature(g)
    # 合并参数(去重,保留顺序)
    merged_params = list(sig_f.parameters.values())
    for name, param in sig_g.parameters.items():
        if name not in sig_f.parameters:
            merged_params.append(param)
    merged_sig = inspect.Signature(parameters=merged_params)

    @functools.wraps(f)
    def merged_func(*args, **kwargs):
        bound_args = merged_sig.bind(*args, **kwargs)
        bound_args.apply_defaults()
        # 调用f时只传递它接受的参数
        f_args = {k: v for k, v in bound_args.arguments.items() if k in sig_f.parameters}
        f(**f_args)
        # 调用g时只传递它接受的参数
        g_args = {k: v for k, v in bound_args.arguments.items() if k in sig_g.parameters}
        g(**g_args)
    
    merged_func.__signature__ = merged_sig
    merged_func.__module__ = f.__module__ if hasattr(f, '__module__') else __name__
    return merged_func

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 10:15:50