Ketik tupel variabel. Bentuk khusus dari tipe variabel yang memungkinkan generik variadik.
class typing.TypeVarTuple(name)
T = TypeVar("T")
Ts = TypeVarTuple("Ts")
def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]:
return (*tup[1:], tup[0])
T is bound to int, Ts is bound to ()
Return value is (1,), which has type tuple[int]
move_first_element_to_last(tup=(1,))
T is bound to int, Ts is bound to (str,)
Return value is ('spam', 1), which has type tuple[str, int]
move_first_element_to_last(tup=(1, 'spam'))
T is bound to int, Ts is bound to (str, float)
Return value is ('spam', 3.0, 1), which has type tuple[str, float, int]
move_first_element_to_last(tup=(1, 'spam', 3.0))
This fails to type check (and fails at runtime)
because tuple[()] is not compatible with tuple[T, *Ts]
(at least one element is required)
move_first_element_to_last(tup=())
x: Ts Not valid
x: tuple[Ts] Not valid
x: tuple[*Ts] The correct way to do it
Shape = TypeVarTuple("Shape")
class Array(Generic[*Shape]):
def __getitem__(self, key: tuple[*Shape]) -> float: ...
def __abs__(self) -> "Array[*Shape]": ...
def get_shape(self) -> tuple[*Shape]: ...
DType = TypeVar('DType')
Shape = TypeVarTuple('Shape')
class Array(Generic[DType, *Shape]): This is fine
pass
class Array2(Generic[*Shape, DType]): This would also be fine
pass
class Height: ...
class Width: ...
float_array_1d: Array[float, Height] = Array() Totally fine
int_array_2d: Array[int, Height, Width] = Array() Yup, fine too