Mental model: Think of type hints as a job description stapled to every function signature. You do not need to open the office door (read the code) to know who works there and what they produce. The hint says: "This role takes two integers and hands back one integer." It is a promise about shape, not value.
Why it matters: In real programs like inventory trackers or sensor dashboards, you often pass data between many functions. Without hints, passing the wrong kind of value (a string where a number belongs) might slide through until the app crashes at 3 AM. Hints let your editor flag that mismatch while you are still writing.
def add(a: int, b: int) -> int:
return a + b
print(add(2, 3))a and b should be ints; the result is an int.The syntax is straightforward. After each parameter name, place a colon and its type. After the closing parenthesis, use an arrow (
These hints are documentation. Python does not enforce them at runtime. If you call
->) to declare the return type.These hints are documentation. Python does not enforce them at runtime. If you call
add('two', 'three'), it will still run and return 'twothree', but your editor can warn you before you hit Enter.Modern collection syntax
def first_even(numbers: list[int]) -> int | None:
for n in numbers:
if n % 2 == 0:
return n
return None
call1 = first_even([3, 7, 8]) # returns 8
call2 = first_even([1, 5, 9]) # returns Nonelist[int] means a list of ints. int | None means an int or nothing.Since Python 3.9 you can write built-in collection types directly:
list[str]— a list of strings.dict[str, int]— keys are str, values are int.set[float],tuple[int, ...]
str | None. It reads as string or none.def lookup(user_id: str) -> dict[str, list[int]]:
data = {'alice': [10, 20], 'bob': [30]}
return {user_id: data.get(user_id, [])}
scores = lookup('alice') # {'alice': [10, 20]}dict[str, list[int]] — a mapping of names to lists of ints.