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

如何为b.b获取tuple[A[int], A[int]]类型?TypeVarTuple展开问题

解决Python typing中TypeVarTuple的逐个泛型展开问题

问题重现

你当前的写法会导致类型被打包成A[*tuple[int, int]]而非逐个展开的tuple[A[int], A[int]],示例代码如下:

from typing import TypeVar, Generic, TypeVarTuple, Unpack, reveal_type

T = TypeVar('T')

class A(Generic[T]):
    pass

Ts = TypeVarTuple('Ts')

class B(Generic[Unpack[Ts]]):
    def __init__(self):
        self.b = (A[int](), A[int]())

b = B[int, int]()
reveal_type(b.b)  # 输出: tuple[A[*tuple[int, int]]]

对比C++的模板展开实现

C++中通过...运算符可以直接展开模板参数包,将每个Ts元素分别传入A:

#include <tuple>

template <typename T>
class A {};

template <typename... Ts>
class B {
public:
    std::tuple<A<Ts>...> b;
    B() : b(std::make_tuple(A<Ts>()...)) {}
};

int main() {
    B<int, int> b;
    // b.b 类型为 std::tuple<A<int>, A<int>>
    return 0;
}

Python中的解决方案

要在Python中实现等价效果,需要将TypeVarTuple的每个元素单独映射到A[T],再通过Unpack展开为元组类型。具体步骤如下:

  1. 定义类型别名,将Ts中的每个元素T映射为A[T]
  2. 在类的属性注解中使用tuple[Unpack[<映射后的类型别名>]]明确类型

修正后的代码:

from typing import TypeVar, Generic, TypeVarTuple, Unpack, reveal_type

T = TypeVar('T')

class A(Generic[T]):
    pass

Ts = TypeVarTuple('Ts')
# 定义类型别名:将Ts的每个元素T转换为A[T]
A_Tuple = tuple[A[T] for T in Ts]

class B(Generic[Unpack[Ts]]):
    b: tuple[Unpack[A_Tuple]]  # 展开映射后的类型为逐个A[T]的元组
    def __init__(self):
        self.b = (A[int](), A[int]())

b = B[int, int]()
reveal_type(b.b)  # 输出: tuple[A[int], A[int]]

关键说明

  • 直接使用tuple[A[*Ts]]会将整个Ts元组作为单一参数传给A,这是导致类型不符合预期的核心原因
  • 类型别名tuple[A[T] for T in Ts]会遍历Ts的每个元素,为每个元素生成对应的A[T]类型
  • 通过Unpack将映射后的类型别名展开为元组的各个元素类型,实现和C++模板参数包展开等价的效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:02:48