← Back to Chapters

Python Type Hinting

? Python Type Hinting

⚡ Quick Overview

Type hinting in Python lets you specify the expected data types of function arguments, return values, and variables. It does not change how Python runs your code, but it improves readability and allows tools (like IDEs and static type checkers) to catch potential bugs before runtime.

Type hints are optional, but they are very helpful in larger projects, team environments, and when maintaining code over time.

? Key Concepts

  • Function type hints describe parameter and return types.
  • Variable type hints document what type a variable should hold.
  • Optional and Union types express multiple possible types.
  • Collection type hints specify the element type of lists, dictionaries, etc.
  • Type hints are checked by tools like mypy, not by the Python interpreter.

? Syntax and Theory

Basic function type hint syntax:

  • parameter_name: Type for annotating parameters.
  • -> ReturnType for annotating the return value.

Variable annotations use the form:

  • variable_name: Type = value

For more complex types, Python provides the typing module, which includes Optional, Union, List, Dict, and many others. In modern Python, you can also use built-in generics like list[int] and dict[str, int].

? Code Examples

➕ Function type hints
# Define a function with typed parameters and return type
def add(a: int, b: int) -> int:
    return a + b

# Annotate the variable that stores the result
result: int = add(5, 3)
? Variable type hints
# Declare variables with explicit type hints
name: str = "Alice"
age: int = 25
scores: list[int] = [90, 85, 88]
? Optional and Union types
# Import typing helpers for Optional and Union
from typing import Optional, Union

# Greet a user whose name may be missing
def greet(name: Optional[str] = None) -> None:
    if name:
        print(f"Hello, {name}")
    else:
        print("Hello, Guest")

# Accept either int or float and process it
def process(value: Union[int, float]) -> None:
    print(value * 2)
? Using type hints with collections
# Use type hints with lists and dictionaries
from typing import List, Dict

# A list of integers
numbers: List[int] = [1, 2, 3, 4]
# A dictionary mapping strings to strings
user_info: Dict[str, str] = {"name": "Alice", "city": "Mumbai"}

? Output and Explanation

? What the code does

  • In add(a: int, b: int) -> int, the hints say that both a and b should be integers and the function returns an integer. Calling add(5, 3) produces 8, and result is annotated as an int.
  • The variable hints like name: str and scores: list[int] tell readers and tools what kind of values they should contain.
  • In greet(name: Optional[str] = None):
    • greet("Alice") prints Hello, Alice.
    • greet() or greet(None) prints Hello, Guest.
  • In process(value: Union[int, float]), value can be either int or float. For example:
    • process(10) prints 20.
    • process(2.5) prints 5.0.
  • The collections examples show how to annotate lists and dictionaries so it is clear that numbers holds integers and user_info maps strings to strings.

✅ Tips & Best Practices

  • Use type hints to improve code readability and maintainability.
  • Adopt type hints gradually: start with public functions and data models.
  • Use tools like mypy, pyright, or IDE inspections to check hints.
  • Keep type hints consistent across a project to avoid confusion.
  • Prefer descriptive types (e.g., dict[str, int]) over plain dict when possible.

? Try It Yourself

  • Write a function rectangle_area that takes width: float and height: float and returns a float. Add proper type hints.
  • Create a function with a parameter that can be None using Optional. For example, a function that optionally takes a username and prints a welcome message.
  • Define a dictionary with type hints using Dict[str, int] to store subject names and marks. Iterate and print them.
  • Run mypy (or another type checker) on a small script and observe the warnings or errors it finds.

?️ When to Use Type Hinting

  • In medium to large codebases where many functions and modules interact.
  • When working in a team so everyone understands expected types quickly.
  • When building libraries or APIs that will be used by other developers.
  • Whenever you want better editor autocompletion and refactoring support.