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

如何静态覆盖函数参数并保留正确的类型提示与文档字符串?

解决方案:创建固定参数的偏函数并保留原函数特性

问题背景

现有函数original,包含指定参数、类型注解及文档字符串。需要定义函数new,本质调用original但固定参数a为A_DEFAULT,要求:

  1. new的签名为原函数移除参数a后的形式(即(b: str))
  2. 保留原函数的文档字符串
  3. 签名和文档能在IDE中正常显示,且无需手动复制原函数的签名与文档

方法1:自定义装饰器 + functools.wraps + 签名修改

通过自定义装饰器固定目标参数,利用functools.wraps继承原函数文档,再通过inspect模块修改函数签名。

import functools
import inspect

A_DEFAULT = 10

def original(a: int, b: str):
    "description"
    return str(a) + b

def fix_first_arg(default_val):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            return func(default_val, *args, **kwargs)
        
        # 修改签名:移除第一个参数a
        sig = inspect.signature(func)
        params = list(sig.parameters.values())[1:]
        new_sig = sig.replace(parameters=params)
        wrapper.__signature__ = new_sig
        return wrapper
    return decorator

new = fix_first_arg(A_DEFAULT)(original)

说明:

  • functools.wraps自动同步原函数的__doc__、__name__等属性
  • 修改__signature__后,IDE能直接识别移除参数后的签名
  • 调用new(x)完全等价于original(A_DEFAULT, x)

方法2:functools.partial + 手动调整属性

functools.partial快速创建偏函数,手动补充文档和签名属性以满足要求:

import functools
import inspect

A_DEFAULT = 10

def original(a: int, b: str):
    "description"
    return str(a) + b

new = functools.partial(original, A_DEFAULT)
# 继承原函数文档
new.__doc__ = original.__doc__
# 修改签名
sig = inspect.signature(original)
params = list(sig.parameters.values())[1:]
new.__signature__ = sig.replace(parameters=params)
# 优化IDE显示:设置函数名
new.__name__ = "new"

说明:

  • functools.partial直接绑定固定参数,逻辑简洁
  • 手动复制文档和修改签名,确保IDE识别正确
  • 代码量少,适合快速实现

方法3:types.FunctionType构造新函数

直接构造新函数,同步原函数关键属性并调整签名:

import types
import inspect
import functools

A_DEFAULT = 10

def original(a: int, b: str):
    "description"
    return str(a) + b

def new_func(b):
    return original(A_DEFAULT, b)

# 同步原函数文档和类型注解
new_func.__doc__ = original.__doc__
new_func.__annotations__ = {k: v for k, v in original.__annotations__.items() if k != "a"}

# 修改签名
sig = inspect.signature(original)
params = list(sig.parameters.values())[1:]
new_func.__signature__ = sig.replace(parameters=params)

# 可选:同步更多原函数属性
functools.wraps(original)(new_func)
new = new_func

说明:

  • 手动定义调用逻辑,灵活性高
  • 过滤类型注解,确保类型检查工具正常工作
  • 可自定义扩展更多函数属性

方法4:可调用类实现(非常规方法)

通过类模拟函数行为,自定义签名和文档:

import inspect
import functools

A_DEFAULT = 10

def original(a: int, b: str):
    "description"
    return str(a) + b

class PartialFunc:
    def __init__(self, func, fixed_arg):
        self.func = func
        self.fixed_arg = fixed_arg
        # 继承原函数文档
        self.__doc__ = func.__doc__
        # 修改签名
        sig = inspect.signature(func)
        params = list(sig.parameters.values())[1:]
        self.__signature__ = sig.replace(parameters=params)
    
    def __call__(self, *args, **kwargs):
        return self.func(self.fixed_arg, *args, **kwargs)

new = PartialFunc(original, A_DEFAULT)

说明:

  • 类的__call__方法实现函数调用逻辑
  • 初始化时直接设置__doc__和__signature__,IDE可识别
  • 适合需要扩展额外功能的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 10:13:19