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

如何检查函数实参类型是否与typing模块指定的类型匹配?

实现类型提示验证装饰器checktypes

下面是满足需求的装饰器实现,支持标准类型和typing模块中的抽象类型(如Iterable),不匹配时会输出清晰的错误信息:

import inspect
import typing
from typing import get_origin, get_args

def checktypes(func):
    # 获取函数签名和类型提示
    func_sig = inspect.signature(func)
    type_hints = typing.get_type_hints(func)

    def wrapper(*args, **kwargs):
        # 绑定传入的实参到函数签名,包含默认参数
        bound_args = func_sig.bind(*args, **kwargs)
        bound_args.apply_defaults()

        for param_name, param_value in bound_args.arguments.items():
            # 跳过没有类型提示的参数
            if param_name not in type_hints:
                continue

            expected_type = type_hints[param_name]
            # 验证参数类型
            is_valid = False

            # 处理泛型类型(如Iterable、List等)
            origin_type = get_origin(expected_type)
            if origin_type is not None:
                is_valid = isinstance(param_value, origin_type)
            else:
                # 处理标准类型(如int、str)
                is_valid = isinstance(param_value, expected_type)

            if not is_valid:
                # 构造格式化的错误信息
                func_name = func.__name__
                # 简化类型名称,去掉typing.前缀
                expected_type_str = str(expected_type).replace("typing.", "")
                actual_type = type(param_value).__name__
                raise TypeError(
                    f"'{param_name}' to '{func_name}()' must be of type '{expected_type_str}', not type '{actual_type}'"
                ) from None

        return func(*args, **kwargs)

    return wrapper

测试示例

使用你提供的测试代码验证效果:

from typing import Iterable

@checktypes
def some_function(arg1: str, arg2: int, arg3: Iterable) -> None:
    pass

# 传入不符合类型的参数
some_function("string", 1, True)

执行后会输出预期的错误:

TypeError: 'arg3' to 'some_function()' must be of type 'Iterable', not type 'bool'

关键细节说明

  1. 参数绑定:用inspect.signature.bind处理位置参数和关键字参数,确保能覆盖所有传入的参数(包括带默认值的参数)
  2. 类型提示解析:typing.get_type_hints比直接读取__annotations__更可靠,会自动解析字符串形式的类型提示(Python 3.9+支持)
  3. 泛型类型处理:通过get_origin获取泛型类型的原始抽象类型(比如typing.Iterable的原始类型是collections.abc.Iterable),确保isinstance判断准确
  4. 错误信息优化:去掉类型名称中的typing.前缀,让错误信息更简洁易读

兼容与扩展说明

  • 对于Python 3.8及以下版本,get_origin和get_args需要从typing_extensions库导入,可通过以下方式兼容:
    try:
        from typing import get_origin, get_args
    except ImportError:
        from typing_extensions import get_origin, get_args
    
  • 当前实现仅验证参数的顶层类型,如果需要验证泛型的元素类型(如List[int]中的int),可以通过get_args获取元素类型后遍历验证
  • 支持联合类型(如Union[int, str]),因为isinstance原生支持传入多个类型进行判断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 17:30:44