文章目录

  • Python 类型注解详解
  • 1. 引言
  • 2. Python 类型注解基础
  • 2.1 变量类型注解
  • 2.2 函数参数和返回值注解
  • 2.3 `typing` 模块的支持
  • 3. 进阶:复杂数据类型
  • 3.1 可选类型(Optional)
  • 3.2 联合类型(Union)
  • 3.3 泛型(Generics)
  • 4. 运行时类型检查
  • 4.1 `get_type_hints()` 获取类型信息
  • 4.2 自定义类型检查装饰器
  • 5. 静态类型检查工具 `mypy`
  • 6. 总结
  • Python 类型注解详解

    1. 引言

    Python 作为一门动态语言,默认不会对变量类型进行强制检查。但在大型项目或多人协作开发时,缺少类型约束可能会导致代码难以维护、调试困难。为了解决这个问题,Python 从 3.5 版本开始引入了 类型注解(Type Hinting),并在后续版本中不断增强。

    本篇文章将详细介绍 Python 类型注解的用法,包括基础语法、高级应用、动态检查、类型推断等内容,帮助你写出更加安全、可读性更强的 Python 代码。


    2. Python 类型注解基础

    2.1 变量类型注解

    Python 允许在变量定义时添加类型注解,但不会影响实际执行。

    # 变量的类型注解
    x: int = 10
    y: str = "Hello"
    z: float = 3.14
    
    print(__annotations__)
    # 输出: {'x': <class 'int'>, 'y': <class 'str'>, 'z': <class 'float'>}
    

    注意

  • __annotations__ 变量会存储所有的全局变量类型信息。
  • 变量的类型注解仅用于静态检查,不会影响运行时的行为。
  • 2.2 函数参数和返回值注解

    函数的参数和返回值可以使用 -> 进行类型标注。

    def add(x: int, y: int) -> int:
        return x + y
    
    print(add.__annotations__)
    # 输出: {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}
    

    这有助于 IDE 提供更好的自动补全,并能被静态分析工具(如 mypy)检查。

    2.3 typing 模块的支持

    对于更复杂的类型,我们可以使用 typing 模块提供的工具,例如 ListDictTuple 等。

    from typing import List, Dict, Tuple
    
    # 列表类型
    numbers: List[int] = [1, 2, 3, 4]
    
    # 字典类型
    user_info: Dict[str, int] = {"age": 25, "height": 175}
    
    # 元组类型
    point: Tuple[int, int] = (10, 20)
    

    3. 进阶:复杂数据类型

    3.1 可选类型(Optional)

    如果某个参数可以是 None,可以使用 Optional 进行标注。

    from typing import Optional
    
    def greet(name: Optional[str]) -> str:
        if name:
            return f"Hello, {name}"
        return "Hello, Guest"
    

    等价于:

    def greet(name: str | None) -> str:  # Python 3.10+ 支持 | 作为联合类型
        return f"Hello, {name or 'Guest'}"
    

    3.2 联合类型(Union)

    如果一个变量可以有多种类型,可以使用 Union

    from typing import Union
    
    def process_data(data: Union[int, str]) -> str:
        return str(data)
    

    3.3 泛型(Generics)

    在处理通用数据结构时,可以使用泛型 TypeVar

    from typing import TypeVar
    
    # 占位符类型
    T = TypeVar("T")
    
    def get_first(items: list[T]) -> T:
        return items[0]
    
    print(get_first([1, 2, 3]))  # 输出: 1
    print(get_first(["a", "b", "c"]))  # 输出: a
    

    4. 运行时类型检查

    4.1 get_type_hints() 获取类型信息

    可以使用 typing.get_type_hints() 在运行时获取类型信息。

    from typing import get_type_hints
    
    def example(a: int, b: str) -> bool:
        return str(a) == b
    
    print(get_type_hints(example))
    # 输出: {'a': <class 'int'>, 'b': <class 'str'>, 'return': <class 'bool'>}
    

    4.2 自定义类型检查装饰器

    可以使用 __annotations__ 编写运行时类型检查装饰器。

    def enforce_types(func):
        def wrapper(*args, **kwargs):
            hints = func.__annotations__
            for arg, (param, expected_type) in zip(args, hints.items()):
                if param != 'return' and not isinstance(arg, expected_type):
                    raise TypeError(f"参数 {param} 应该是 {expected_type}, 但接收到 {type(arg)}")
            return func(*args, **kwargs)
        return wrapper
    
    @enforce_types
    def multiply(a: int, b: int) -> int:
        return a * b
    
    print(multiply(2, 3))  # 正常执行
    print(multiply("2", 3))  # 抛出 TypeError
    

    5. 静态类型检查工具 mypy

    Python 类型注解主要用于静态检查,推荐使用 mypy 进行检查。

    安装 mypy

    pip install mypy
    

    运行静态检查

    mypy my_script.py
    

    如果 my_script.py 中有类型错误,mypy 会报错。


    6. 总结

    Python 的类型注解可以帮助提高代码可读性和可维护性,并且可以结合 mypy 进行静态检查。本篇文章介绍了:

    ✅ 变量、函数的基础类型注解
    typing 模块的高级类型(OptionalUnion、泛型等)
    ✅ 运行时类型检查的方法
    mypy 进行静态类型检查

    若有错误与不足请指出,关注DPT一起进步吧!!!

    作者:叫我DPT

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python 类型注解

    发表回复