Python 3类型,自定义可变参数泛型类型,包含任意数量的类型,如何实现?

xpcnnkqh  于 2023-11-20  发布在  Python
关注(0)|答案(2)|浏览(122)

typing.Tuple可以与任意数量的类型参数一起使用,如Tuple[int, str, MyClass]Tuple[str, float]。我如何实现我自己的类可以像这样使用?我知道如何从typing.Generic继承。下面的代码演示了这一点。

from typing import TypeVar, Generic

T = TypeVar("T")

class Thing(Generic[T]):
    def __init__(self, value: T):
        self.value = value

def f(thing: Thing[int]):
    print(thing.value)

if __name__ == '__main__':
    t = Thing("WTF")
    f(t)

字符串
上面的代码可以工作,但是类型检查器(在我的例子中是PyCharm)会发现t的类型应该是Thing[int]而不是Thing[str]。这一切都很好,但是我如何让类Thing支持任意数量的类型参数,就像Tuple一样?

7gcisfzg

7gcisfzg1#

就像@metatoaster在他们的评论中所说的那样,这可以使用TypeVarTuple,从3.11开始在typing中可用,否则typing_extensions

from typing import Generic, TypeVarTuple

Ts = TypeVarTuple("Ts")

class Thing(Generic[*Ts]):
    def __init__(self, *value: *Ts):
        self.value = value

def f(thing: Thing[int]):
    print(thing.value)

t = Thing("WTF")  # Type of "t" is "Thing[str]"
f(t)  # error: Type parameter "Ts@Thing" is invariant, but "*tuple[str]" is not the same as "*tuple[int]"

字符串

inkz8wg9

inkz8wg92#

  • 在你的例子中,t的类型是Thing,而不是Thing[str]。所以这个对象接受T的任何东西。
  • 你可以像这样参数化它:t2 = Thing[str]("WTF")
  • 现在,对于你的问题,我认为你想使用打字。联盟这样:t3=Thing[Union[str,int,float]]("WTF")

顺便说一下,您可以使用来自typing_inspect的get_generic_type()检查泛型的类型

>>> get_generic_type(t)
__main__.Thing
>>> get_generic_type(t2)
__main__.Thing[str]
>>> get_generic_type(t3)
__main__.Thing[typing.Union[str, int, float]]

字符串

相关问题