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

如何将typing.Callable类型提示转换为inspect.Signature函数签名对象?

如何将typing.Callable类型提示转换为inspect.Signature函数签名对象?

场景说明

假设你定义了这样的Callable类型提示:

hint = typing.Callable[[int], float]

要同时用它做类型提示,还要筛选符合该签名的函数,核心是把这个类型提示转成inspect.Signature对象,再和目标函数的签名做对比。

实现方法

要完成转换,关键是提取Callable泛型里的参数类型列表和返回值类型,再用inspect.Signature和inspect.Parameter手动构建签名对象。下面是具体的代码实现:

转换函数

import inspect
import typing
from typing import Callable, Any

def callable_to_signature(callable_hint) -> inspect.Signature:
    # 校验输入是否为Callable泛型实例
    if not (isinstance(callable_hint, typing._GenericAlias) and callable_hint.__origin__ is Callable):
        raise TypeError("输入必须是typing.Callable的泛型类型提示")
    
    args_types, return_type = callable_hint.__args__
    
    # 处理Callable[..., 返回值]的情况(接受任意参数)
    if args_types is Ellipsis:
        parameters = [
            inspect.Parameter('*args', inspect.Parameter.VAR_POSITIONAL, annotation=Any),
            inspect.Parameter('**kwargs', inspect.Parameter.VAR_KEYWORD, annotation=Any)
        ]
    else:
        # 生成位置参数,参数名用arg0、arg1...自动命名
        parameters = []
        for idx, arg_type in enumerate(args_types):
            param = inspect.Parameter(
                name=f'arg{idx}',
                kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
                annotation=arg_type
            )
            parameters.append(param)
    
    # 构建并返回签名对象
    return inspect.Signature(parameters=parameters, return_annotation=return_type)

测试示例

用你给出的类型提示测试:

hint = typing.Callable[[int], float]
sig = callable_to_signature(hint)
print(sig)  # 输出: (arg0: int) -> float

签名对比

如果要验证某个函数是否符合该签名,可以提取函数的签名后,对比参数类型和返回值类型:

def func(a: int) -> float:
    return float(a)

# 获取函数的签名
func_sig = inspect.signature(func)

# 定义对比逻辑(忽略参数名,只看类型)
def signatures_match(sig1: inspect.Signature, sig2: inspect.Signature) -> bool:
    if len(sig1.parameters) != len(sig2.parameters):
        return False
    # 逐个对比参数的注解类型
    for p1, p2 in zip(sig1.parameters.values(), sig2.parameters.values()):
        if p1.annotation != p2.annotation:
            return False
    # 对比返回值类型
    return sig1.return_annotation == sig2.return_annotation

print(signatures_match(sig, func_sig))  # 输出: True

注意事项

  • 转换后的参数名是自动生成的arg0、arg1,和实际函数的参数名可能不同,所以对比时只关注类型注解即可
  • 支持处理Callable[..., float]这种接受任意参数的类型提示
  • 如果输入是不带泛型的typing.Callable,其__args__为(Any, Any),你可以根据需求修改函数逻辑,比如默认处理为任意参数或抛出错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 11:01:04