如何让Python新函数与原函数签名一致并被IDE识别?
问题描述
现有原函数:
def my_original_func(a1, a2, a3, a4, a5): print(a1, a2, a3, a4, a5)
想要创建新函数my_new_func,采用如下结构:
@a_decorator(my_original_func) def my_new_func(*args, **kwargs): pass
预想的装饰器实现大致如下:
def a_decorator(func): def wrapper(*args, **kwargs): func_sig = inspect.signature(func) def my_copy_func(*args, **kwargs): return func(*args, **kwargs) my_copy_func.__signature__ = func_sig return my_copy_func return wrapper
核心诉求
- 无需为
my_new_func显式声明与原函数一致的参数列表 - 原函数签名变更时,不用同步修改多个同结构函数的参数
- 让PyCharm等IDE能识别
my_new_func的参数与原函数完全匹配,调用时给出准确的参数提示,而非仅显示*args和**kwargs
解决方案
你当前的装饰器实现逻辑有误:它返回的是内部函数my_copy_func,但my_new_func被装饰后实际指向的是wrapper,而wrapper的签名仍是*args, **kwargs,IDE自然无法识别原函数的参数。正确的做法是直接修改被装饰函数的签名属性,同时保留自定义包装逻辑。
修改后的装饰器实现
import inspect def a_decorator(target_func): def decorator(wrapped_func): # 定义包装逻辑 def wrapper(*args, **kwargs): # 这里可以添加自定义包装代码,比如前置/后置处理 print("执行my_new_func前置逻辑") result = target_func(*args, **kwargs) print("执行my_new_func后置逻辑") return result # 将原函数的签名赋值给wrapper,让IDE识别参数 wrapper.__signature__ = inspect.signature(target_func) return wrapper return decorator
使用方式
@a_decorator(my_original_func) def my_new_func(*args, **kwargs): pass
效果说明
- 调用
my_new_func时,PyCharm等IDE会显示与my_original_func完全一致的参数提示(a1, a2, a3, a4, a5) - 后续修改
my_original_func的参数列表时,my_new_func的参数提示会自动同步更新,无需修改my_new_func的定义
进阶优化(同步更多函数属性)
如果需要让my_new_func更贴近原函数的属性(比如文档字符串、注解等),可以结合functools.wraps实现:
import inspect import functools def a_decorator(target_func): def decorator(wrapped_func): @functools.wraps(wrapped_func) def wrapper(*args, **kwargs): print("自定义包装逻辑") return target_func(*args, **kwargs) # 同步原函数的签名、文档字符串和注解 wrapper.__signature__ = inspect.signature(target_func) wrapper.__doc__ = target_func.__doc__ wrapper.__annotations__ = target_func.__annotations__ return wrapper return decorator
内容的提问来源于stack exchange,提问作者user112495
相关产品推荐
相关产品推荐

