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

如何为接收可调用对象及其必填位置参数的函数添加类型提示?

正确实现方式

方案1:使用ParamSpec

若要兼容带关键字参数的函数,需同时声明*args: P.args和**kwargs: P.kwargs以满足类型检查要求,修正后的代码如下:

from typing import ParamSpec, TypeVar, Callable

P = ParamSpec("P")
T = TypeVar("T")

def call_func(func: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T:
    return func(*args, **kwargs)

如果你的call_func仅打算传递位置参数、不处理关键字参数,这种场景更适合使用TypeVarTuple。

方案2:使用TypeVarTuple

需通过Unpack展开TypeVarTuple(Python 3.11+可从typing导入Unpack,低于该版本需从typing_extensions导入),修正后的代码如下:

from typing import TypeVarTuple, TypeVar, Callable
from typing_extensions import Unpack  # Python <3.11需导入此模块

Ts = TypeVarTuple("Ts")
T = TypeVar("T")

def call_func(func: Callable[Unpack[Ts], T], *args: Unpack[Ts]) -> T:
    return func(*args)
TypeVarTuple与ParamSpec的技术差异
  • 用途定位:
    • ParamSpec用于完整捕获函数的参数签名(包含位置参数、关键字参数、默认值等所有参数信息),适合需要保留原函数完整参数结构的场景(比如装饰器)。
    • TypeVarTuple仅用于表示一组可变数量的位置参数类型,无法处理关键字参数,适合只关注位置参数序列的简单场景。
  • 语法与兼容性:
    • ParamSpec是PEP 612定义的特性,Mypy支持更成熟,整体兼容性更好。
    • TypeVarTuple是PEP 646定义的可变泛型特性,需要启用--enable-incomplete-feature=TypeVarTuple才能使用,语法要求更严格(必须用Unpack展开)。
  • 表达能力:
    • ParamSpec可区分位置参数与关键字参数,还能结合Concatenate实现参数拼接(比如给原函数新增参数的装饰器场景)。
    • TypeVarTuple仅能处理位置参数的可变序列,无法单独表示关键字参数,表达范围更窄。

内容的提问来源于stack exchange,提问作者S.B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 20:08:18