如何为透传至其他函数的kwargs添加动态类型提示?
问题
假设有一个仅接受关键字参数、且带有完整类型提示的方法:
class A: def func(a: int, b: str, c: SomeIntricateTypeHint) -> OutputClass: ...
另有一个函数接收可变关键字参数,并将其完整传递给上述方法:
def outer_func(n_repeat: int, **kwargs: ???) -> OtherOutputClass: a = A() for _ in range(n_repeat): a.func(**kwargs)
此时func的类型提示优势会丢失,请问如何为outer_func的kwargs添加类型提示以恢复该优势?
补充说明:实际场景中func并非自定义方法,而是boto3客户端对象的方法,因此需要无需手动创建TypedDict的动态类型提示方案。
解决方案
要动态继承目标方法的关键字参数类型提示,无需手动编写TypedDict,可以利用Python的类型系统特性或运行时工具实现:
方案1:用PEP 612的ParamSpec约束参数(推荐)
Python 3.10+支持的ParamSpec可以捕获目标方法的参数签名,直接将其应用到outer_func的kwargs上,让类型检查器自动关联参数约束:
from typing import TypeVar, ParamSpec, Callable P = ParamSpec("P") R = TypeVar("R") def outer_func(n_repeat: int, **kwargs: P.kwargs) -> OtherOutputClass: a = A() # 显式声明目标方法的类型,引导类型检查器识别参数结构 target_func: Callable[P, R] = a.func for _ in range(n_repeat): target_func(**kwargs)
这种方式完全依赖静态类型检查,不需要额外的运行时代码,能完美保留func的类型提示优势。
方案2:运行时提取参数类型(辅助验证)
如果需要同时在运行时验证参数类型,可以用typing.get_type_hints提取目标方法的类型信息:
from typing import get_type_hints, Any def outer_func(n_repeat: int, **kwargs: Any) -> OtherOutputClass: a = A() func_type_hints = get_type_hints(a.func) # 可选:运行时验证参数类型 for param_name, expected_type in func_type_hints.items(): if param_name in kwargs and not isinstance(kwargs[param_name], expected_type): raise TypeError(f"参数 {param_name} 类型错误,预期 {expected_type}") for _ in range(n_repeat): a.func(**kwargs)
类型检查器可以通过get_type_hints的分析间接关联目标方法的类型,同时运行时的验证能进一步保证参数合法性。
针对boto3客户端方法的适配
对于boto3客户端方法,只需安装对应的类型存根(如boto3-stubs[s3]),再用ParamSpec关联目标方法即可:
from typing import TypeVar, ParamSpec, Callable import boto3 P = ParamSpec("P") R = TypeVar("R") def outer_func(n_repeat: int, **kwargs: P.kwargs) -> OtherOutputClass: s3_client = boto3.client("s3") # 关联目标方法的类型,比如s3的list_objects_v2 target_func: Callable[P, R] = s3_client.list_objects_v2 for _ in range(n_repeat): target_func(**kwargs)
类型检查器会自动识别boto3存根中定义的方法参数类型,约束outer_func的kwargs完全匹配目标方法的要求。
内容的提问来源于stack exchange,提问作者ticster
相关产品推荐
相关产品推荐

