When I write a function expecting a specific-length tuple, I can type the argument with Tuple[int, int]
(for a specific length of two).
from typing import Tuple
def tuple_in(a_tuple: Tuple[int, int]) -> Tuple[int, int]:
return a_tuple
tuple_in((0, 1)) # mypy is happy
That's great as long as I have a tuple to pass. If I don't have a tuple, I have trouble casting whatever I do have into a tuple.
tuple_in(tuple([0, 1])) # Expected Tuple[int, int], got Tuple[int, ...]
tuple_in(tuple(x for x in [0, 1])) # Expected Tuple[int, int], got Tuple[int, ...]
tuple_in(tuple(x for x in [0, 1][:2])) # Expected Tuple[int, int], got Tuple[int, ...]
I get it. Casting an argument of indeterminate length yields a tuple of indeterminate length. But that makes my life difficult.
This works, but it's not really work able with more than 2-3 values
my_list = [0, 1]
tuple_in((my_list[0], my_list[1])) # mypy is happy. My eyes hurt.
The typing module has a cast
function to cast those Tuple[int, ...]
into Tuple[int, int]
, but that's no better than type: ignore
.
tuple_in(cast(Tuple[int, int], "obviously not a tuple")) # mypy is happy
Fortunately, the typing module offers a better solution: NamedTuple
from typing import NamedTuple
TwoInts = NamedTuple("TwoInts", [("a", int), ("b", int)])
def named_tuple_in(a_tuple: TwoInts) -> Tuple[int, int]:
return a_tuple
named_tuple_in(Tuple2(*[0, 1])) # mypy is happy
BUT, if I want to call tuple_in
from outside the module, I've got to import TwoInts
. That seems like overkill, and it means my editor won't give me much of a hint (only the name of my NamedTuple).
I like the NamedTuple solution when my argument makes sense as a weak class (eg, Vector3, GenusSpecies, Address), but it doesn't feel like the best solution for generic, fixed-length arguments (eg, TwoInts, FourteenScalars, ThreeNames).
What is the intended way to type such fixed-length arguments?
I found it!!
from typing import Tuple
def tuple_in(a_tuple: Tuple[int, int]) -> Tuple[int, int]:
return a_tuple
tuple_in([0, 1])[:2] # mypy is happy!!!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.