I'm starting to learn type hints in Python to ease the future porting of code from Python to C. I am wondering what the difference is, if any, between using types directly in type hints vs. using the classes defined in the typing
module.
For example, the difference between
def somefn(a: list[int]) -> tuple[str, int]:
...
and
from typing import List, Tuple
def somefn(a: List[int]) -> Tuple[str, int]:
...
It seems like some classes like Union
, Any
, Callable
, and Iterable
would be useful, but the utility of classes for data types that already exist as keywords in python is unclear to me.
As of 3.9, the standard collections can serve as type hints, so the typing
types aren't strictly necessary, and are generally inferior to using the built-ins themselves; you can continue to use the typing
types if you like (necessary for code that must run on pre-3.9 Python), but it's not necessary if you can rely on 3.9+.
Remainder of answer covers the situation pre-3.9.
It's useful for writing annotations that can be legally evaluated; list[int]
will explode if you try to actually run it, while typing.List[int]
returns a new generic type that knows the type of both container and contents. This is particularly important in the case of type aliases, where a specialized version of a generic is defined at the top level, then reused as annotation further on:
Vector = List[float]
def scale(scalar: float, vector: Vector) -> Vector:
...
is legal, while:
Vector = list[float]
def scale(scalar: float, vector: Vector) -> Vector:
...
blows up in your face. You'll note that non-container/generic types typically don't have a typing
type (exceptions like Text
are for porting concerns), because type aliases would only use them as "leaf" type, not root or branch types.