使用类型定义方法的未打包参数

1 投票
1 回答
28 浏览
提问于 2025-04-14 18:30

假设我有一个类型:

class MyType(Generic[T, U]):
    def foo(self, *args: T) -> U:
        pass

m = MyType[tuple[int, bool], str]

我想要能够像这样提供参数:

m.foo(1, True)

而不是像这样:

m.foo((1, True))

有没有办法在一个方法中使用泛型,这样如果我有一个包含多个参数的类型,我可以在方法中将它们拆开?

我看到我可以使用:

P = ParamSpec("P")

但我想在 P.args 上加一个类型限制,让它等于 T。

1 个回答

1

TypeVarTuple 是你需要的东西:它可以收集不确定数量的类型参数,并允许你在后面进行拆解。

(练习链接: mypy, Pyright)

class MyType[*Ts, U]:

    def foo(self, *args: *Ts) -> U:
        ...
m = MyType[int, bool, str]()    # No extra brackets

reveal_type(m.foo(1, True))     # mypy => str
                                # Pyright => str

在 Python 3.10 或更早的版本中:

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

Ts = TypeVarTuple('Ts')
U = TypeVar('U')

class MyType(Generic[*Ts, U]):

    def foo(self, *args: Unpack[Ts]) -> U:
        ...

或者,使用 ParamSpec

(练习链接: mypy, Pyright)

class MyType[**P, U]:

    def foo(self, *args: P.args, **kwargs: P.kwargs) -> U:
        ...
m = MyType[[int, bool], str]()  # One extra pair

撰写回答