如何为接收类型元组并返回对应类型对象的函数添加类型标注?
为接收类型元组的函数添加动态Union返回类型标注
要实现让类型检查器识别allowed_types为类型对象元组,并将返回值推断为这些类型的Union,需要用到PEP 646引入的TypeVarTuple和Unpack来处理可变数量的类型参数。你之前的写法错误在于使用了*而非Unpack来展开类型元组,这是PEP 646规定的语法。
正确的safe_convert实现
首先导入必要的类型工具,然后定义类型变量元组,再修正函数的类型标注:
from typing import Any, TypeVarTuple, Unpack, Union Ts = TypeVarTuple('Ts') def safe_convert[*Ts](value: Any, allowed_types: tuple[Unpack[type[Ts]]]) -> Union[Unpack[Ts]]: if isinstance(value, allowed_types): return value raise TypeError(f"Value must be an instance of one of {allowed_types}")
扩展示例的safe_get实现
将同样的逻辑应用到你的AllTheThings类中,注意同时修正_things的类型标注:
from typing import Any, TypeVarTuple, Unpack, Union Ts = TypeVarTuple('Ts') class AllTheThings: def __init__(self): self._things: dict[str, Any] = {} def put(self, key: str, value: Any) -> None: self._things[key] = value def safe_get[*Ts](self, key: str, allowed_types: tuple[Unpack[type[Ts]]]) -> Union[Unpack[Ts]]: value = self._things[key] if isinstance(value, allowed_types): return value raise TypeError(f"Value for key '{key}' must be an instance of one of {allowed_types}") things = AllTheThings() things.put("foo", "a") things.put("bar", 42) things.put("baz", {}) thing = things.safe_get("foo", (int, str)) reveal_type(thing) # 类型检查器将推断为 Union[int, str]
关键说明
TypeVarTuple('Ts')用于捕获一组可变数量的类型参数,对应传入allowed_types的各个类型对象。tuple[Unpack[type[Ts]]]表示allowed_types是一个元组,其中每个元素是Ts中对应类型的类型对象(比如int对应type[int])。Union[Unpack[Ts]]将捕获的类型参数展开为Union类型,作为函数的返回值。- 确保你的类型检查器支持PEP 646:mypy需要开启
enable_pep646 = True(或使用Python 3.11+),pyright默认支持该特性。
内容的提问来源于stack exchange,提问作者Filipp
相关产品推荐
相关产品推荐

