类
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
那样?
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]"
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]]