SoFunction
Updated on 2025-05-21

A very detailed guide to the example of Python type annotations

Python type annotation detailed guide

Type Annotations are an important feature introduced in Python 3.5+, which allows developers to explicitly declare types of variables, function parameters, and return values.

1. Basic type annotation

Python's built-in basic types can be used directly for annotations:

# Variable Annotationname: str = "Alice"
age: int = 30
price: float = 19.99
is_active: bool = True

# Function parameters and return value annotationsdef greet(name: str) -> str:
    return f"Hello, {name}"

2. Compound type annotation

For more complex types, you can usetypingTools in the module:

from typing import List, Dict, Tuple, Set, Optional

# Listnumbers: List[int] = [1, 2, 3]

# dictionaryperson: Dict[str, str] = {"name": "Alice", "email": "alice@"}

# Tuple (fixed length and type)point: Tuple[float, float] = (3.14, 2.71)

# gatherunique_numbers: Set[int] = {1, 2, 3}

# Optional type (indicates that it may be None)middle_name: Optional[str] = None

3. Function type annotation

Functions can explain parameters and return value types in detail:

from typing import Callable

# Basic function annotationdef add(a: int, b: int) -> int:
    return a + b

# Parameters with default valuesdef greet(name: str, greeting: str = "Hello") -> str:
    return f"{greeting}, {name}"

# function as parameterdef apply_func(func: Callable[[int, int], int], x: int, y: int) -> int:
    return func(x, y)

4. Special types

typingModules provide many special types:

from typing import Any, Union, NoReturn

# Any - Any typedef log(message: Any) -> None:
    print(message)

# Union - Multiple possible typesdef square(number: Union[int, float]) -> Union[int, float]:
    return number ** 2

# NoReturn - The function will not return normallydef fail() -> NoReturn:
    raise Exception("Something went wrong")

5. Type alias

Create alias for complex types to improve readability:

from typing import List, Tuple

# Simple aliasUserId = int

# Complex aliasPoint = Tuple[float, float]
Vector = List[float]

def normalize(vector: Vector) -> Vector:
    length = sum(x**2 for x in vector) ** 0.5
    return [x/length for x in vector]

6. Generics

Use generics to create reusable type templates:

from typing import TypeVar, Generic, List

T = TypeVar('T')  # Declare type variables
class Stack(Generic[T]):
    def __init__(self) -> None:
        : List[T] = []
    
    def push(self, item: T) -> None:
        (item)
    
    def pop(self) -> T:
        return ()

# useint_stack = Stack[int]()
int_stack.push(1)

7. Type variables

Type variables allow constraints on possible types:

from typing import TypeVar, Union

# Unconstrained type variablesT = TypeVar('T')

# Constrained type variablesNumber = TypeVar('Number', int, float, complex)

def double(x: Number) -> Number:
    return x * 2

8. Custom Type

Custom types can be created:

from typing import NewType, TypedDict

# New TypeUserId = NewType('UserId', int)

def get_user_name(user_id: UserId) -> str:
    return f"user_{user_id}"

# Typed Dictionary (Python 3.8+)class Person(TypedDict):
    name: str
    age: int
    email: Optional[str]

person: Person = {"name": "Alice", "age": 30}

9. Type Checking Tool

Commonly used type checking tools:

  • mypy: The most popular static type checker
  • pyright: Type checker developed by Microsoft
  • pytype: Type checker developed by Google

Install mypy:

pip install mypy

Run type check:

mypy your_script.py

10. Things to note

  • Progressive typing: You can add type annotations step by step, without completing them in one go
  • Prioritize public API: Prioritize the annotation of module interfaces, function parameters and return values
  • Use strict mode: Used in mypy--strictThe strictest check for sign acquisition
  • Stay consistent: Consistent annotation style throughout the project
  • Documents and types complement each other: Type annotations cannot completely replace documents, and important behaviors still require documentation instructions
  • Avoid overuse of Any: Try to use specific types, Any will lose the benefits of type checking
  • Utilizing type inference: Simple local variables can omit type annotations

Summarize

Although the use of type annotations in Python seems to be contrary to the dynamic type characteristics of Python, this is actually a practice actively promoted by the Python community in recent years and has important practical significance. Python's type annotation system provides powerful tools to enhance the readability and maintainability of code, while potential errors can be detected early in development through static type checking. With the continuous evolution of the Python type system, type annotation is becoming a standard practice for large Python projects, with the following advantages:

(1) Code readability and documentization

  • Explicit contract: The type annotation clearly declares the expected type of parameters and return values, making the semantics of the function interface clear at a glance. For exampledef get_user(id: int) -> UserIt is clearer than the unannotated version.
  • Alternative partial comments: Reduce the text description of parameter types (such as# x should be an integer), express the intention directly through grammar.

(2) Static type check

  • Tool support: In conjunction with static type checking tools (such asmypypyright, PyCharm built-in checks), can catch type-related errors before the code runs. For example:

    func(x="hello")  # Static check will report an error: Expected 'int', got 'str'
  • Discover errors in advance: Avoid type errors during runtimeAttributeErrororTypeError, especially suitable for large-scale projects.

(3) IDE intelligent support

  • Code completion: IDE can provide more accurate attribute/method suggestions based on type annotations (such as knowingy: strAfterwards, entery.Will promptstrmethod).
  • Refactoring security: When renaming variables and modifying interfaces, the IDE can ensure consistency through type checking.

(4) Project maintenance

  • Long-term maintenance: In multi-person collaboration or long-term projects, type annotations lower the threshold for understanding code and reduce bugs caused by type obfuscation.
  • Progressive typing: Python allows a mix of annotated and non-annotated code, suitable for gradual migration of old projects.

Type annotation is a type in PythonOptional enhancement tools, it improves the reliability and maintainability of the code through static type checking, while retaining the runtime flexibility of dynamic types. Although not mandatory, it has become a highly recommended practice in modern Python development (especially large projects). Its necessity depends on the project size, team habits and maintenance cycle, and rational use can significantly reduce long-term maintenance costs.

This is the end of this article about Python type annotations. For more related Python type annotations, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!