# `typing` --- 类型提示支持

3.5 新版功能.

源码： Lib/typing.py

注解

Python 运行时不强制执行函数和变量类型注解，但这些注解可用于类型检查器、IDE、静态检查器等第三方工具。

本模块为 PEP 484 、PEP 526 、PEP 544 、PEP 586 、PEP 589 和 PEP 591 中的类型提示提供运行时支持。`Any`、`Union`、`Tuple`、`Callable`、`TypeVar` 和 `Generic` 等类型是最基础的组件。完整说明详见 PEP 484，类型提示简介请参阅 PEP 483。

下面的函数接收、并返回字符串，注解方式如下：

    def greeting(name: str) -> str:
        return 'Hello ' + name

`greeting` 函数中，参数 `name` 的类型是 `str`，返回类型也是 `str`。子类型也可以当作参数。

## 类型别名

把类型赋给别名，就可以定义类型别名。本例中，`Vector` 和 `list[float]` 的意义相同，可互换：

    Vector = list[float]

    def scale(scalar: float, vector: Vector) -> Vector:
        return [scalar * num for num in vector]

    # typechecks; a list of floats qualifies as a Vector.
    new_vector = scale(2.0, [1.0, -4.2, 5.4])

类型别名适用于简化复杂的类型签名。例如：

    from collections.abc import Sequence

    ConnectionOptions = dict[str, str]
    Address = tuple[str, int]
    Server = tuple[Address, ConnectionOptions]

    def broadcast_message(message: str, servers: Sequence[Server]) -> None:
        ...

    # The static type checker will treat the previous type signature as
    # being exactly equivalent to this one.
    def broadcast_message(
            message: str,
            servers: Sequence[tuple[tuple[str, int], dict[str, str]]]) -> None:
        ...

注意，`None` 是一种类型提示特例，已被 `type(None)` 取代。

## NewType

`NewType()` 辅助函数可创建不同的新类型：

    from typing import NewType

    UserId = NewType('UserId', int)
    some_id = UserId(524313)

静态类型检查器把新类型当作原始类型的子类，这种方式适用于捕捉逻辑错误：

    def get_user_name(user_id: UserId) -> str:
        ...

    # typechecks
    user_a = get_user_name(UserId(42351))

    # does not typecheck; an int is not a UserId
    user_b = get_user_name(-1)

`UserId` 类型的变量可执行所有 `int` 操作，但返回结果都是 `int` 类型。这种方式允许在预期 `int` 时传入 `UserId`，还能防止意外创建无效的 `UserId`：

    # 'output' is of type 'int', not 'UserId'
    output = UserId(23413) + UserId(54341)

注意，只有静态类型检查器强制执行这些检查。在运行时，`Derived = NewType('Derived', Base)` 语句把 `Derived` 当作函数，该函数直接返回传递给它的任何参数。即，`Derived(some_value)` 表达式不创建新类，或引入超出调用常规函数的开销。

更确切地说，在运行时，`some_value is Derived(some_value)` 表达式总为 True。

也就是说，不能创建 `Derived` 的子类型，因为，在运行时，它是标识函数，不是真正的类型：

    from typing import NewType

    UserId = NewType('UserId', int)

    # Fails at runtime and does not typecheck
    class AdminUserId(UserId): pass

但是，可以基于 '派生的' `NewType` 创建 `NewType()`：

    from typing import NewType

    UserId = NewType('UserId', int)

    ProUserId = NewType('ProUserId', UserId)

同时，`ProUserId` 的类型检查也可以按预期执行。

详见 PEP 484。

注解

回顾上文，类型别名声明了两种彼此 等价 的类型。 `Alias = Original` 时，静态类型检查器认为 `Alias` 与 `Original` 完全等价。 这种方式适用于简化复杂类型签名。

反之，`NewType` 声明把一种类型当作另一种类型的 子类型。`Derived = NewType('Derived', Original)` 时，静态类型检查器把 `Derived` 当作 `Original` 的 子类 ，即，`Original` 类型的值不能用在预期 `Derived` 类型的位置。这种方式适用于以最小运行时成本防止逻辑错误。

3.5.2 新版功能.

## 可调对象（Callable）

预期特定签名回调函数的框架可以用 `Callable[[Arg1Type, Arg2Type], ReturnType]` 实现类型提示。

例如：

    from collections.abc import Callable

    def feeder(get_next_item: Callable[[], str]) -> None:
        # Body

    def async_query(on_success: Callable[[int], None],
                    on_error: Callable[[int, Exception], None]) -> None:
        # Body

无需指定调用签名，用省略号字面量替换类型提示里的参数列表： `Callable[..., ReturnType]`，就可以声明可调对象的返回类型。

## 泛型（Generic）

容器中，对象的类型信息不能以泛型方式静态推断，因此，抽象基类扩展支持下标，用于表示容器元素的预期类型。

    from collections.abc import Mapping, Sequence

    def notify_by_email(employees: Sequence[Employee],
                        overrides: Mapping[str, str]) -> None: ...

typing 模块中新推出的 `TypeVar` 工厂函数实现泛型参数化。

    from collections.abc import Sequence
    from typing import TypeVar

    T = TypeVar('T')      # Declare type variable

    def first(l: Sequence[T]) -> T:   # Generic function
        return l[0]

## 用户定义的泛型类型

用户定义的类可以定义为泛型类。

    from typing import TypeVar, Generic
    from logging import Logger

    T = TypeVar('T')

    class LoggedVar(Generic[T]):
        def __init__(self, value: T, name: str, logger: Logger) -> None:
            self.name = name
            self.logger = logger
            self.value = value

        def set(self, new: T) -> None:
            self.log('Set ' + repr(self.value))
            self.value = new

        def get(self) -> T:
            self.log('Get ' + repr(self.value))
            return self.value

        def log(self, message: str) -> None:
            self.logger.info('%s: %s', self.name, message)

`Generic[T]` 是定义类 `LoggedVar` 的基类，该类使用单类型参数 `T`。在该类体内，`T` 是有效的类型。

`Generic` 基类定义了 `__class_getitem__()` ，因此，`LoggedVar[t]` 也是有效类型：

    from collections.abc import Iterable

    def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
        for var in vars:
            var.set(0)

泛型类型支持多个类型变量，不过，类型变量可能会受到限制：

    from typing import TypeVar, Generic
    ...

    T = TypeVar('T')
    S = TypeVar('S', int, str)

    class StrangePair(Generic[T, S]):
        ...

`Generic` 类型变量的参数应各不相同。下列代码就是无效的：

    from typing import TypeVar, Generic
    ...

    T = TypeVar('T')

    class Pair(Generic[T, T]):   # INVALID
        ...

`Generic` 支持多重继承：

    from collections.abc import Sized
    from typing import TypeVar, Generic

    T = TypeVar('T')

    class LinkedList(Sized, Generic[T]):
        ...

继承自泛型类时，可以修正某些类型变量：

    from collections.abc import Mapping
    from typing import TypeVar

    T = TypeVar('T')

    class MyDict(Mapping[str, T]):
        ...

比如，本例中 `MyDict` 调用的单参数，`T`。

未指定泛型类的类型参数时，每个位置的类型都预设为 `Any`。下例中，`MyIterable` 不是泛型，但却隐式继承了 `Iterable[Any]`：

    from collections.abc import Iterable

    class MyIterable(Iterable): # Same as Iterable[Any]

还支持用户定义的泛型类型别名。例如：

    from collections.abc import Iterable
    from typing import TypeVar, Union
    S = TypeVar('S')
    Response = Union[Iterable[S], int]

    # Return type here is same as Union[Iterable[str], int]
    def response(query: str) -> Response[str]:
        ...

    T = TypeVar('T', int, float, complex)
    Vec = Iterable[tuple[T, T]]

    def inproduct(v: Vec[T]) -> T: # Same as Iterable[tuple[T, T]]
        return sum(x*y for x, y in v)

在 3.7 版更改: `Generic` 不再支持自定义元类。

抽象基类可作为用户定义的泛型类的基类，且不会与元类冲突。现已不再支持泛型元类。参数化泛型的输出结果会被缓存，typing 模块的大多数类型都可哈希、可进行等价对比。

## `Any` 类型

`Any` 是一种特殊的类型。静态类型检查器认为所有类型均与 `Any` 兼容，同样，`Any` 也与所有类型兼容。

也就是说，可对 `Any` 类型的值执行任何操作或方法调用，并赋值给任意变量：

    from typing import Any

    a = None    # type: Any
    a = []      # OK
    a = 2       # OK

    s = ''      # type: str
    s = a       # OK

    def foo(item: Any) -> int:
        # Typechecks; 'item' could be any type,
        # and that type might have a 'bar' method
        item.bar()
        ...

注意，`Any` 类型的值赋给更精确的类型时，不执行类型检查。例如，把 `a` 赋给 `s`，在运行时，即便 `s` 已声明为 `str` 类型，但接收 `int` 值时，静态类型检查器也不会报错。

此外，未指定返回值与参数类型的函数，都隐式地默认使用 `Any`：

    def legacy_parser(text):
        ...
        return data

    # A static type checker will treat the above
    # as having the same signature as:
    def legacy_parser(text: Any) -> Any:
        ...
        return data

需要混用动态与静态类型代码时，此操作把 `Any` 当作 应急出口。

`Any` 和 `object` 的区别。与 `Any` 相似，所有类型都是 `object` 的子类型。然而，与 `Any` 不同，object 不可逆：`object` 不是 其它类型的子类型。

就是说，值的类型是 `object` 时，类型检查器几乎会拒绝所有对它的操作，并且，把它赋给更精确的类型变量（或返回值）属于类型错误。例如：

    def hash_a(item: object) -> int:
        # Fails; an object does not have a 'magic' method.
        item.magic()
        ...

    def hash_b(item: Any) -> int:
        # Typechecks
        item.magic()
        ...

    # Typechecks, since ints and strs are subclasses of object
    hash_a(42)
    hash_a("foo")

    # Typechecks, since Any is compatible with all types
    hash_b(42)
    hash_b("foo")

使用 `object`，说明值能以类型安全的方式转为任何类型。使用 `Any`，说明值是动态类型。

## 名义子类型 vs 结构子类型

PEP 484 最初只是把 Python 静态类型系统定义为应用 名义子类型。即，当且仅当 `A` 是 `B` 的子类时，才能在预期 `B` 类时应用 `A` 类。

此项要求以前也适用于抽象基类，例如，`Iterable` 。这种方式的问题在于，定义类时必须显式说明，既不 Pythonic，也不是动态类型式 Python 代码的惯用写法。例如，下列代码就遵从了 PEP 484 的规范：

    from collections.abc import Sized, Iterable, Iterator

    class Bucket(Sized, Iterable[int]):
        ...
        def __len__(self) -> int: ...
        def __iter__(self) -> Iterator[int]: ...

PEP 544 允许用户在类定义时不显式说明基类，从而解决了这一问题，静态类型检查器隐式认为 `Bucket` 既是 `Sized` 的子类型，又是 `Iterable[int]` 的子类型。这就是 结构子类型 （又称为静态鸭子类型）：

    from collections.abc import Iterator, Iterable

    class Bucket:  # Note: no base classes
        ...
        def __len__(self) -> int: ...
        def __iter__(self) -> Iterator[int]: ...

    def collect(items: Iterable[int]) -> int: ...
    result = collect(Bucket())  # Passes type check

此外，结构子类型的优势在于，通过继承特殊类 `Protocol` ，用户可以定义新的自定义协议（见下文中的例子）。

## 模块内容

本模块定义了下列类、函数和修饰器。

注解

本模块定义了一些类型，作为标准库中已有的类的子类，从而可以让 `Generic` 支持 `[]` 中的类型变量。Python 3.9 中，这些标准库的类已支持 `[]` ，因此，这些类型就变得冗余了。

Python 3.9 弃用了这些冗余类型，但解释器并未提供相应的弃用警告。标记弃用类型的工作留待支持 Python 3.9 及以上版本的类型检查器实现。

Python 3.9.0 发布五年后的首个 Python 发行版将从 `typing` 模块中移除这些弃用类型。详见 PEP 585 《标准集合的类型提示泛型》。

### 特殊类型原语

#### 特殊类型

这些类型可用于类型注解，但不支持 `[]`。

`typing.``Any`

  不受限的特殊类型。

  - 所有类型都与 `Any` 兼容。

  - `Any` 与所有类型都兼容。

`typing.``NoReturn`

  标记没有返回值的函数的特殊类型。例如：

      from typing import NoReturn

      def stop() -> NoReturn:
          raise RuntimeError('no way')

  3.5.4 新版功能.

  3.6.2 新版功能.

#### 特殊形式

可用于类型注解，且支持 `[]` ，每种形式都有其独特的句法。

`typing.``Tuple`

  元组类型； `Tuple[X, Y]` 是二项元组类型，第一个元素的类型是 X，第二个元素的类型是 Y。空元组的类型可写为 `Tuple[()]`。

  例：`Tuple[T1, T2]` 是二项元组，类型变量分别为 T1 和 T2。`Tuple[int, float, str]` 是由整数、浮点数、字符串组成的三项元组。

  可用省略号字面量指定同质变长元组，例如，`Tuple[int, ...]` 。`Tuple` 与 `Tuple[Any, ...]` 等价，也与 `tuple` 等价。

  3.9 版后已移除: `builtins.tuple` 现已支持 `[]`。详见 PEP 585 与 Generic Alias Type。

`typing.``Union`

  联合类型；`Union[X, Y]` 的意思是，非 X 即 Y。

  可用 `Union[int, str]` 等形式定义联合类型。 具体如下：

  - 参数必须是某种类型，且至少有一个。

  - 联合类型之联合类型会被展平，例如：

        Union[Union[int, str], float] == Union[int, str, float]

  - 单参数之联合类型就是该参数自身，例如：

        Union[int] == int  # The constructor actually returns int

  - 冗余的参数会被跳过，例如：

        Union[int, str, int] == Union[int, str]

  - 比较联合类型，不涉及参数顺序，例如：

        Union[int, str] == Union[str, int]

  - 联合类型不能作为子类，也不能实例化。

  - 不支持 `Union[X][Y]` 这种写法。

  - `Optional[X]` 是 `Union[X, None]` 的缩写。

  在 3.7 版更改: 在运行时，不要移除联合类型中的显式子类。

`typing.``Optional`

  可选类型。

  `Optional[X]` 等价于 `Union[X, None]` 。

  注意，可选类型与含默认值的可选参数不同。含默认值的可选参数不需要在类型注解上添加 `Optional` 限定符，因为它仅是可选的。例如：

      def foo(arg: int = 0) -> None:
          ...

  另一方面，显式应用 `None` 值时，不管该参数是否可选， `Optional` 都适用。例如：

      def foo(arg: Optional[int] = None) -> None:
          ...

`typing.``Callable`

  可调类型； `Callable[[int], str]` 是把（int）转为 str 的函数。

  下标句法必须与参数列表和返回类型这两个值一起使用。参数列表只能是类型列表或省略号；返回类型只能是单一类型。

  没有说明可选参数或关键字参数的句法；这类函数类型很少用作回调类型。`Callable[..., ReturnType]` （省略号字面量）可用于为接受任意数量参数，并返回 `ReturnType` 的可调对象提供类型提示。纯 `Callable` 等价于 `Callable[..., Any]`，进而等价于 `collections.abc.Callable` 。

  3.9 版后已移除: `collections.abc.Callable` 现已支持 `[]`。 详见 PEP 585 与 Generic Alias Type。

class `typing.``Type`(Generic[CT_co])

  用 `C` 注解的变量可以接受类型 `C` 的值。反之，用 `Type[C]` 注解的变量可以接受类自身的值 — 准确地说，是接受 `C` 的 类对象，例如：

      a = 3         # Has type 'int'
      b = int       # Has type 'Type[int]'
      c = type(a)   # Also has type 'Type[int]'

  注意，`Type[C]` 为协变量：

      class User: ...
      class BasicUser(User): ...
      class ProUser(User): ...
      class TeamUser(User): ...

      # Accepts User, BasicUser, ProUser, TeamUser, ...
      def make_new_user(user_class: Type[User]) -> User:
          # ...
          return user_class()

  `Type[C]` 为协变量的意思是指， `C` 的所有子类都应使用与 `C` 相同的构造器签名及类方法签名。类型检查器应标记违反此项规定的内容，但也应允许符合指定基类构造器调用的子类进行构造器调用。PEP 484 修订版将来可能会调整类型检查器对这种特例的处理方式。

  `Type` 合法的参数仅有类、`Any` 、类型变量 以及上述类型的联合类型。例如：

      def new_non_team_user(user_class: Type[Union[BasicUser, ProUser]]): ...

  `Type[Any]` 等价于 `Type`，进而等价于 Python 元类架构的根基，`type`。

  3.5.2 新版功能.

  3.9 版后已移除: `builtins.type` 现已支持 `[]`。详见 PEP 585 与 Generic Alias Type。

`typing.``Literal`

  表示类型检查器对应变量或函数参数的值等价于给定字面量（或多个字面量之一）的类型。例如：

      def validate_simple(data: Any) -> Literal[True]:  # always returns True
          ...

      MODE = Literal['r', 'rb', 'w', 'wb']
      def open_helper(file: str, mode: MODE) -> str:
          ...

      open_helper('/some/path', 'r')  # Passes type check
      open_helper('/other/path', 'typo')  # Error in type checker

  `Literal[...]` 不能创建子类。在运行时，任意值均可作为 `Literal[...]` 的类型参数，但类型检查器可以对此加以限制。字面量类型详见 PEP 586 。

  3.8 新版功能.

  在 3.9.1 版更改: `Literal` 现已支持参数去重。`Literal` 对象的等价对比不再依赖顺序。`Literal` 对象中有不是 immutable 的参数时，会触发 `TypeError` 异常。

`typing.``ClassVar`

  标记类变量的特殊类型构造器。

  如 PEP 526 所述，打包在 ClassVar 内的变量注解是指，给定属性应当用作类变量，而不应设置在类实例上。用法如下：

      class Starship:
          stats: ClassVar[dict[str, int]] = {} # class variable
          damage: int = 10                     # instance variable

  `ClassVar` 仅接受类型，也不能使用下标。

  `ClassVar` 本身不是类，不应用于 `isinstance()` 或 `issubclass()`。`ClassVar` 不改变 Python 运行时行为，但可以用于第三方类型检查器。例如，类型检查器会认为以下代码有错：

      enterprise_d = Starship(3000)
      enterprise_d.stats = {} # Error, setting class variable on instance
      Starship.stats = {}     # This is OK

  3.5.3 新版功能.

`typing.``Final`

  告知类型检查器某名称不能再次赋值或在子类中重写的特殊类型构造器。例如：

      MAX_SIZE: Final = 9000
      MAX_SIZE += 1  # Error reported by type checker

      class Connection:
          TIMEOUT: Final[int] = 10

      class FastConnector(Connection):
          TIMEOUT = 1  # Error reported by type checker

  这些属性没有运行时检查。详见 PEP 591。

  3.8 新版功能.

`typing.``Annotated`

  PEP 593 （`灵活函数和变量注解`）里引入的类型，可以用上下文特定元数据（`Annotated` 的参数可变，也可能用它的多个组成部分）装饰现有的类型。具体来说，就是类型提示 `Annotated[T, x]` 用元数据 `x` 注解类型 `T`。静态分析或运行时都能使用该元数据。库（或工具）处理类型提示 `Annotated[T, x]` 时，在元数据 `x` 不涉及特殊逻辑的情况下，可忽略该类型提示，仅把它当作类型 `T`。与 `typing` 模块中现有的 `no_type_check` 功能不同，该功能完全禁用了函数或类的类型检查注解，而 `Annotated` 类型则允许对 `T` 进行静态类型检查（例如，通过 mypy 或 Pyre，可安全地忽略 `x`），也可以在特定应用程序中实现 `x` 的运行时访问。

  毕竟，如何解释注解（如有）由处理 `Annotated` 类型的工具/库负责。工具/库处理 `Annotated` 类型时，扫描所有注解以确定是否需要进行处理（例如，使用 `isinstance()`）。

  工具/库不支持注解，或遇到未知注解时，应忽略注解，并把注解类型当作底层类型。

  是否允许客户端在一个类型上使用多个注解，以及如何合并这些注解，由处理注解的工具决定。

  `Annotated` 类型支持把多个相同（或不同）的单个（或多个）类型注解置于任意节点。因此，使用这些注解的工具/库要负责处理潜在的重复项。例如，执行值范围分析时，应允许以下操作：

      T1 = Annotated[int, ValueRange(-10, 5)]
      T2 = Annotated[T1, ValueRange(-20, 3)]

  传递 `include_extras=True` 至 `get_type_hints()` ，即可在运行时访问额外的注解。

  语义详情：

  - `Annotated` 的第一个参数必须是有效类型。

  - 支持多个类型标注（`Annotated` 支持可变参数）：

        Annotated[int, ValueRange(3, 10), ctype("char")]

  - 调用 `Annotated` 至少要有两个参数（`Annotated[int]` 是无效的）

  - 注解的顺序会被保留，且影响等价检查：

        Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[
            int, ctype("char"), ValueRange(3, 10)
        ]

  - 嵌套 `Annotated` 类型会被展平，元数据从最内层注解依序展开：

        Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[
            int, ValueRange(3, 10), ctype("char")
        ]

  - 不移除注解重复项：

        Annotated[int, ValueRange(3, 10)] != Annotated[
            int, ValueRange(3, 10), ValueRange(3, 10)
        ]

  - `Annotated` 可用于嵌套或泛型别名：

        T = TypeVar('T')
        Vec = Annotated[list[tuple[T, T]], MaxLen(10)]
        V = Vec[int]

        V == Annotated[list[tuple[int, int]], MaxLen(10)]

  3.9 新版功能.

#### 构建泛型类型

以下内容是创建泛型类型的基石，但不在注解内使用。

class `typing.``Generic`

  用于泛型类型的抽象基类。

  泛型类型一般通过继承含一个或多个类型变量的类实例进行声明。例如，泛型映射类型定义如下：

      class Mapping(Generic[KT, VT]):
          def __getitem__(self, key: KT) -> VT:
              ...
              # Etc.

  该类的用法如下：

      X = TypeVar('X')
      Y = TypeVar('Y')

      def lookup_name(mapping: Mapping[X, Y], key: X, default: Y) -> Y:
          try:
              return mapping[key]
          except KeyError:
              return default

class `typing.``TypeVar`

  类型变量。

  用法：

      T = TypeVar('T')  # Can be anything
      A = TypeVar('A', str, bytes)  # Must be str or bytes

  类型变量主要是为静态类型检查器提供支持，用于泛型类型与泛型函数定义的参数。有关泛型类型，详见 `Generic`。泛型函数的写法如下：

      def repeat(x: T, n: int) -> Sequence[T]:
          """Return a list containing n references to x."""
          return [x]*n

      def longest(x: A, y: A) -> A:
          """Return the longest of two strings."""
          return x if len(x) >= len(y) else y

  本质上，后例的签名重载了 `(str, str) -> str` 与 `(bytes, bytes) -> bytes`。注意，参数是 `str` 子类的实例时，返回类型仍是纯 `str`。

  在运行时，`isinstance(x, T)` 会触发 `TypeError` 异常。一般而言，`isinstance()` 和 `issubclass()` 不应与类型搭配使用。

  通过 `covariant=True` 或 `contravariant=True` 可以把类型变量标记为协变量或逆变量。详见 PEP 484。默认情况下，类型变量是不变量。类型变量还可以用 `bound=<type>` 指定上限。这里的意思是，（显式或隐式地）取代类型变量的实际类型必须是限定类型的子类，详见 PEP 484。

`typing.``AnyStr`

  `AnyStr` 类型变量的定义为 `AnyStr = TypeVar('AnyStr', str, bytes)`。

  这里指的是，它可以接受任意同类字符串，但不支持混用不同类别的字符串。例如：

      def concat(a: AnyStr, b: AnyStr) -> AnyStr:
          return a + b

      concat(u"foo", u"bar")  # Ok, output has type 'unicode'
      concat(b"foo", b"bar")  # Ok, output has type 'bytes'
      concat(u"foo", b"bar")  # Error, cannot mix unicode and bytes

class `typing.``Protocol`(Generic)

  Protocol 类的基类。Protocol 类的定义如下：

      class Proto(Protocol):
          def meth(self) -> int:
              ...

  这些类主要与静态类型检查器搭配使用，用来识别结构子类型（静态鸭子类型），例如：

      class C:
          def meth(self) -> int:
              return 0

      def func(x: Proto) -> int:
          return x.meth()

      func(C())  # Passes static type check

  详见 PEP 544。Protocol 类用 `runtime_checkable()` （见下文）装饰，忽略类型签名，仅检查给定属性是否存在，充当简要的运行时协议。

  Protocol 类可以是泛型，例如：

      class GenProto(Protocol[T]):
          def meth(self) -> T:
              ...

  3.8 新版功能.

`@``typing.``runtime_checkable`

  用于把 Protocol 类标记为运行时协议。

  该协议可以与 `isinstance()` 和 `issubclass()` 一起使用。应用于非协议的类时，会触发 `TypeError`。该指令支持简易结构检查，与 `collections.abc` 的 `Iterable` 非常类似，只擅长做一件事。 例如：

      @runtime_checkable
      class Closable(Protocol):
          def close(self): ...

      assert isinstance(open('/some/file'), Closable)

  注解

  `runtime_checkable()` 只检查所需方法是否存在，但却不检查类型签名！ 例如，`builtins.complex` 支持 `__float__()`，因此，它能通过 `SupportsFloat` 的 `issubclass()` 检查。 然而，`complex.__float__` 方法其实只是为了触发含更多信息的 `TypeError`。

  3.8 新版功能.

#### 其他特殊指令

这些特殊指令是声明类型的基石，但不在注解内使用。

class `typing.``NamedTuple`

  `collections.namedtuple()` 的类型版本。

  用法：

      class Employee(NamedTuple):
          name: str
          id: int

  相当于：

      Employee = collections.namedtuple('Employee', ['name', 'id'])

  为字段提供默认值，要在类体内赋值：

      class Employee(NamedTuple):
          name: str
          id: int = 3

      employee = Employee('Guido')
      assert employee.id == 3

  带默认值的字段必须在不带默认值的字段后面。

  生成的类具有 `__annotations__` 这个附加属性，提供了映射字段名与字段类型的字典。（字段名在 `_fields` 属性内，默认值在 `_field_defaults` 属性内，这两项都是命名元组 API 的组成部分。）

  `NamedTuple` 子类也支持文档字符串与方法：

      class Employee(NamedTuple):
          """Represents an employee."""
          name: str
          id: int = 3

          def __repr__(self) -> str:
              return f'<Employee {self.name}, id={self.id}>'

  反向兼容用法：

      Employee = NamedTuple('Employee', [('name', str), ('id', int)])

  在 3.6 版更改: 添加了对 PEP 526 中变量注解句法的支持。

  在 3.6.1 版更改: 添加了对默认值、方法、文档字符串的支持。

  在 3.8 版更改: `_field_types` 和 `__annotations__` 属性现已使用常规字典，不再使用 `OrderedDict` 实例。

  在 3.9 版更改: 移除了 `_field_types` 属性， 改用具有相同信息，但更标准的 `__annotations__` 属性。

`typing.``NewType`(name, tp)

  用于为类型检查器标明不同类型的辅助函数，详见 NewType。在运行时，它返回一个返回其参数的函数。用法如下：

      UserId = NewType('UserId', int)
      first_user = UserId(1)

  3.5.2 新版功能.

class `typing.``TypedDict`(dict)

  把类型提示添加至字典的特殊构造器。在运行时，它是纯 `dict`。

  `TypedDict` 声明一个字典类型，该类型预期所有实例都具有一组键集，其中，每个键都与对应类型的值关联。运行时不检查此预期，而是由类型检查器强制执行。用法如下：

      class Point2D(TypedDict):
          x: int
          y: int
          label: str

      a: Point2D = {'x': 1, 'y': 2, 'label': 'good'}  # OK
      b: Point2D = {'z': 3, 'label': 'bad'}           # Fails type check

      assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')

  用于内省的类型信息可通过 `Point2D.__annotations__` 和 `Point2D.__total__` 访问。为了让不支持 PEP 526 的老版 Python 也能使用此功能，`TypedDict` 支持两个附加的等价句法形式：

      Point2D = TypedDict('Point2D', x=int, y=int, label=str)
      Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})

  默认情况下，所有键都必须列在 TypedDict 里。不过，也可以通过指定 total 参数进行重写。用法如下：

      class point2D(TypedDict, total=False):
          x: int
          y: int

  这段代码的意思是，可以省略 point2D 这个 TypedDict 中的任意键。类型检查器只支持字面量 False 或 True 作为 total 参数的值。True 是默认值，表明在类体中，必须定义所有项目。

  更多示例与 `TypedDict` 的详细规则，详见 PEP 589。

  3.8 新版功能.

### 泛型具象容器

#### 对应的内置类型

class `typing.``Dict`(dict, MutableMapping[KT, VT])

  `dict` 的泛型版本。适用于注解返回类型。注解参数时，最好使用 `Mapping` 等抽象容器类型。

  该类型用法如下：

      def count_words(text: str) -> Dict[str, int]:
          ...

  3.9 版后已移除: `builtins.dict` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``List`(list, MutableSequence[T])

  `list` 的泛型版本。适用于注解返回类型。注解参数时，最好使用 `Sequence` 或 `Iterable` 等抽象容器类型。

  该类型用法如下：

      T = TypeVar('T', int, float)

      def vec2(x: T, y: T) -> List[T]:
          return [x, y]

      def keep_positives(vector: Sequence[T]) -> List[T]:
          return [item for item in vector if item > 0]

  3.9 版后已移除: `builtins.list` 现已支持 `[]`。详见 PEP 585 与 Generic Alias Type。

class `typing.``Set`(set, MutableSet[T])

  `builtins.set` 的泛型版本。适用于注解返回类型。注解参数时，最好使用 `AbstractSet` 等抽象容器类型。

  3.9 版后已移除: `builtins.set` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``FrozenSet`(frozenset, AbstractSet[T_co])

  `builtins.frozenset` 的泛型版本。

  3.9 版后已移除: `builtins.frozenset` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

注解

`Tuple` 是一种特殊形式。

#### `collections` 对应类型

class `typing.``DefaultDict`(collections.defaultdict, MutableMapping[KT, VT])

  `collections.defaultdict` 的泛型版本。

  3.5.2 新版功能.

  3.9 版后已移除: `collections.defaultdict` 现已支持 `[]`。详见 PEP 585 与 Generic Alias Type。

class `typing.``OrderedDict`(collections.OrderedDict, MutableMapping[KT, VT])

  `collections.OrderedDict` 的泛型版本。

  3.7.2 新版功能.

  3.9 版后已移除: `collections.OrderedDict` 现已支持 `[]`。详见 PEP 585 与 Generic Alias Type。

class `typing.``ChainMap`(collections.ChainMap, MutableMapping[KT, VT])

  `collections.ChainMap` 的泛型版本。

  3.5.4 新版功能.

  3.6.1 新版功能.

  3.9 版后已移除: `collections.ChainMap` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``Counter`(collections.Counter, Dict[T, int])

  `collections.Counter` 的泛型版本。

  3.5.4 新版功能.

  3.6.1 新版功能.

  3.9 版后已移除: `collections.Counter` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``Deque`(deque, MutableSequence[T])

  `collections.deque` 的泛型版本。

  3.5.4 新版功能.

  3.6.1 新版功能.

  3.9 版后已移除: `collections.deque` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

#### 其他具象类型

class `typing.``IO`
class `typing.``TextIO`
class `typing.``BinaryIO`

  泛型类型 `IO[AnyStr]` 及其子类 `TextIO(IO[str])` 与 `BinaryIO(IO[bytes])` 表示由 `open()` 返回的 I/O 流的类型。 这些类型也在 `typing.io` 命名空间里。

class `typing.``Pattern`
class `typing.``Match`

  这些类型对应的是从 `re.compile()` 与 `re.match()`.返回的类型。这些类型（及对应的函数）是 `AnyStr` 的泛型，且可以通过 `Pattern[str]`、`Pattern[bytes]`、`Match[str]`、`Match[bytes]` 指定具体类型。这些类型也在 `typing.re` 的命名空间里。

  3.9 版后已移除: `re` 模块中的 `Pattern` 与 `Match` 类现已支持 `[]`。详见 PEP 585 与 Generic Alias Type。

class `typing.``Text`

  `Text` 是 `str` 的别名。提供了对 Python 2 代码的向下兼容：Python 2 中，`Text` 是 `unicode` 的别名。

  使用 `Text` 时，值中必须包含 unicode 字符串，以兼容 Python 2 和 Python 3：

      def add_unicode_checkmark(text: Text) -> Text:
          return text + u' \u2713'

  3.5.2 新版功能.

### 抽象基类

#### `collections.abc` 对应的容器

class `typing.``AbstractSet`(Sized, Collection[T_co])

  `collections.abc.Set` 的泛型版本。

  3.9 版后已移除: `collections.abc.Set` 现已支持 `[]`。详见 PEP 585 与 Generic Alias Type。

class `typing.``ByteString`(Sequence[int])

  `collections.abc.ByteString` 的泛型版本。

  该类型代表了 `bytes`、`bytearray`、`memoryview` 等字节序列类型。

  作为该类型的简称，`bytes` 可用于标注上述任意类型的参数。

  3.9 版后已移除: `collections.abc.ByteString` 现已支持 `[]`。详见 PEP 585 与 Generic Alias Type。

class `typing.``Collection`(Sized, Iterable[T_co], Container[T_co])

  `collections.abc.Collection` 的泛型版本。

  3.6.0 新版功能.

  3.9 版后已移除: `collections.abc.Collection` 现已支持 `[]`。详见 PEP 585 与 Generic Alias Type。

class `typing.``Container`(Generic[T_co])

  `collections.abc.Container` 的泛型版本。

  3.9 版后已移除: `collections.abc.Container` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``ItemsView`(MappingView, Generic[KT_co, VT_co])

  `collections.abc.ItemsView` 的泛型版本。

  3.9 版后已移除: `collections.abc.ItemsView` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``KeysView`(MappingView[KT_co], AbstractSet[KT_co])

  `collections.abc.KeysView` 的泛型版本。

  3.9 版后已移除: `collections.abc.KeysView` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``Mapping`(Sized, Collection[KT], Generic[VT_co])

  `collections.abc.Mapping` 的泛型版本。用法如下：

      def get_position_in_index(word_list: Mapping[str, int], word: str) -> int:
          return word_list[word]

  3.9 版后已移除: `collections.abc.Mapping` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``MappingView`(Sized, Iterable[T_co])

  `collections.abc.MappingView` 的泛型版本。

  3.9 版后已移除: `collections.abc.MappingView` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``MutableMapping`(Mapping[KT, VT])

  `collections.abc.MutableMapping` 的泛型版本。

  3.9 版后已移除: `collections.abc.MutableMapping` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``MutableSequence`(Sequence[T])

  `collections.abc.MutableSequence` 的泛型版本。

  3.9 版后已移除: `collections.abc.MutableSequence` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``MutableSet`(AbstractSet[T])

  `collections.abc.MutableSet` 的泛型版本。

  3.9 版后已移除: `collections.abc.MutableSet` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``Sequence`(Reversible[T_co], Collection[T_co])

  `collections.abc.Sequence` 的泛型版本。

  3.9 版后已移除: `collections.abc.Sequence` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``ValuesView`(MappingView[VT_co])

  `collections.abc.ValuesView` 的泛型版本。

  3.9 版后已移除: `collections.abc.ValuesView` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

#### `collections.abc` 对应的其他类型

class `typing.``Iterable`(Generic[T_co])

  `collections.abc.Iterable` 的泛型版本。

  3.9 版后已移除: `collections.abc.Iterable` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``Iterator`(Iterable[T_co])

  `collections.abc.Iterator` 的泛型版本。

  3.9 版后已移除: `collections.abc.Iterator` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``Generator`(Iterator[T_co], Generic[T_co, T_contra, V_co])

  生成器可以由泛型类型 `Generator[YieldType, SendType, ReturnType]` 注解。例如：

      def echo_round() -> Generator[int, float, str]:
          sent = yield 0
          while sent >= 0:
              sent = yield round(sent)
          return 'Done'

  注意，与 typing 模块里的其他泛型不同， `Generator` 的 `SendType` 属于逆变行为，不是协变行为，也是不变行为。

  如果生成器只产生值，可将 `SendType` 与 `ReturnType` 设为 `None`：

      def infinite_stream(start: int) -> Generator[int, None, None]:
          while True:
              yield start
              start += 1

  此外，还可以把生成器的返回类型注解为 `Iterable[YieldType]` 或 `Iterator[YieldType]`：

      def infinite_stream(start: int) -> Iterator[int]:
          while True:
              yield start
              start += 1

  3.9 版后已移除: `collections.abc.Generator` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``Hashable`

  `collections.abc.Hashable` 的别名。

class `typing.``Reversible`(Iterable[T_co])

  `collections.abc.Reversible` 的泛型版本。

  3.9 版后已移除: `collections.abc.Reversible` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``Sized`

  `collections.abc.Sized` 的别名。

#### 异步编程

class `typing.``Coroutine`(Awaitable[V_co], Generic[T_co, T_contra, V_co])

  `collections.abc.Coroutine` 的泛型版本。类型变量的差异和顺序与 `Generator` 的内容相对应，例如：

      from collections.abc import Coroutine
      c = None # type: Coroutine[list[str], str, int]
      ...
      x = c.send('hi') # type: list[str]
      async def bar() -> None:
          x = await c # type: int

  3.5.3 新版功能.

  3.9 版后已移除: `collections.abc.Coroutine` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``AsyncGenerator`(AsyncIterator[T_co], Generic[T_co, T_contra])

  异步生成器可由泛型类型 `AsyncGenerator[YieldType, SendType]` 注解。例如：

      async def echo_round() -> AsyncGenerator[int, float]:
          sent = yield 0
          while sent >= 0.0:
              rounded = await round(sent)
              sent = yield rounded

  与常规生成器不同，异步生成器不能返回值，因此没有 `ReturnType` 类型参数。 与 `Generator` 类似，`SendType` 也属于逆变行为。

  如果生成器只产生值，可将 `SendType` 设置为 `None`：

      async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
          while True:
              yield start
              start = await increment(start)

  此外，可用 `AsyncIterable[YieldType]` 或 `AsyncIterator[YieldType]` 注解生成器的返回类型：

      async def infinite_stream(start: int) -> AsyncIterator[int]:
          while True:
              yield start
              start = await increment(start)

  3.6.1 新版功能.

  3.9 版后已移除: `collections.abc.AsyncGenerator` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``AsyncIterable`(Generic[T_co])

  `collections.abc.AsyncIterable` 的泛型版本。

  3.5.2 新版功能.

  3.9 版后已移除: `collections.abc.AsyncIterable` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``AsyncIterator`(AsyncIterable[T_co])

  `collections.abc.AsyncIterator` 的泛型版本。

  3.5.2 新版功能.

  3.9 版后已移除: `collections.abc.AsyncIterator` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``Awaitable`(Generic[T_co])

  `collections.abc.Awaitable` 的泛型版本。

  3.5.2 新版功能.

  3.9 版后已移除: `collections.abc.Awaitable` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

#### 上下文管理器类型

class `typing.``ContextManager`(Generic[T_co])

  `contextlib.AbstractContextManager` 的泛型版本。

  3.5.4 新版功能.

  3.6.0 新版功能.

  3.9 版后已移除: `contextlib.AbstractContextManager` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

class `typing.``AsyncContextManager`(Generic[T_co])

  `contextlib.AbstractAsyncContextManager` 的泛型版本。

  3.5.4 新版功能.

  3.6.2 新版功能.

  3.9 版后已移除: `contextlib.AbstractAsyncContextManager` 现已支持 `[]`。详见 PEP 585 和 Generic Alias Type。

### 协议

这些协议由 `runtime_checkable()` 装饰。

class `typing.``SupportsAbs`

  含抽象方法 `__abs__` 的抽象基类，是其返回类型里的协变量。

class `typing.``SupportsBytes`

  含抽象方法 `__bytes__` 的抽象基类。

class `typing.``SupportsComplex`

  含抽象方法 `__complex__` 的抽象基类。

class `typing.``SupportsFloat`

  含抽象方法 `__float__` 的抽象基类。

class `typing.``SupportsIndex`

  含抽象方法 `__index__` 的抽象基类。

  3.8 新版功能.

class `typing.``SupportsInt`

  含抽象方法 `__int__` 的抽象基类。

class `typing.``SupportsRound`

  含抽象方法 `__round__` 的抽象基类，是其返回类型的协变量。

### 函数与装饰器

`typing.``cast`(typ, val)

  把值强制转换为类型。

  不变更返回值。对类型检查器而言，代表了返回值具有指定的类型，但运行时故意不做任何检查（以便让检查速度尽量快）。

`@``typing.``overload`

  `@overload` 装饰器可以修饰支持多个不同参数类型组合的函数或方法。`@overload` - 装饰定义的系列必须紧跟一个非 `@overload`-装饰定义（用于同一个函数/方法）。`@overload`-装饰定义仅是为了协助类型检查器， 因为该装饰器会被非 `@overload`-装饰定义覆盖，后者用于运行时，而且会被类型检查器忽略。在运行时直接调用 `@overload` 装饰的函数会触发 `NotImplementedError`。下面的重载示例给出了比联合类型或类型变量更精准的类型：

      @overload
      def process(response: None) -> None:
          ...
      @overload
      def process(response: int) -> tuple[int, str]:
          ...
      @overload
      def process(response: bytes) -> str:
          ...
      def process(response):
          <actual implementation>

  详见 PEP 484，与其他类型语义进行对比。

`@``typing.``final`

  告知类型检查器被装饰的方法不能被覆盖，且被装饰的类不能作为子类的装饰器，例如：

      class Base:
          @final
          def done(self) -> None:
              ...
      class Sub(Base):
          def done(self) -> None:  # Error reported by type checker
                ...

      @final
      class Leaf:
          ...
      class Other(Leaf):  # Error reported by type checker
          ...

  这些属性没有运行时检查。详见 PEP 591。

  3.8 新版功能.

`@``typing.``no_type_check`

  标明注解不是类型提示的装饰器。

  用作类或函数的 decorator。用于类时，递归地应用于该类中定义的所有方法，（但不影响超类或子类中定义的方法）。

  本方法可直接修改函数。

`@``typing.``no_type_check_decorator`

  让其他装饰器具有 `no_type_check()` 效果的装饰器。

  本装饰器用 `no_type_check()` 里的装饰函数打包其他装饰器。

`@``typing.``type_check_only`

  标记类或函数内不可用于运行时的装饰器。

  在运行时，该装饰器本身不可用。实现返回的是私有类实例时，它主要是用于标记在类型存根文件中定义的类。

      @type_check_only
      class Response:  # private or not available at runtime
          code: int
          def get_header(self, name: str) -> str: ...

      def fetch_response() -> Response: ...

  注意，建议不要返回私有类实例，最好将之设为公共类。

### 内省辅助器

`typing.``get_type_hints`(obj, globalns=None, localns=None, include_extras=False)

  返回函数、方法、模块、类对象的类型提示的字典。

  一般情况下，与 `obj.__annotations__` 相同。此外，可通过在 `globals` 与 `locals` 命名空间里进行评估，以此来处理编码为字符串字面量的前向引用。如有需要，在默认值设置为 `None` 时，可为函数或方法注解添加 `Optional[t]`。对于类 `C`，则返回由所有 `__annotations__` 与 `C.__mro__` 逆序合并而成的字典。

  本函数以递归地方式用 `T` 替换所有 `Annotated[T, ...]`， 除非将 `include_extras` 的值设置为 `True` （详见 `Annotated`）。例如：

      class Student(NamedTuple):
          name: Annotated[str, 'some marker']

      get_type_hints(Student) == {'name': str}
      get_type_hints(Student, include_extras=False) == {'name': str}
      get_type_hints(Student, include_extras=True) == {
          'name': Annotated[str, 'some marker']
      }

  在 3.9 版更改: PEP 593 的组成部分，添加了 `include_extras` 参数。

`typing.``get_args`(tp)

`typing.``get_origin`(tp)

  为泛型类型与特殊类型形式提供了基本的内省功能。

  对于 `X[Y, Z, ...]` 形式的类型对象，这些函数返回 `X` 与 `(Y, Z, ...)`。如果 `X` 是内置对象或 `collections` class 的泛型别名， 会将其标准化为原始类。如果 `X` 是包含在其他泛型类型中的 `Union` 或 `Literal`，`(Y, Z, ...)` 的顺序会因类型缓存，而与原始参数 `[Y, Z, ...]` 的顺序不同。对于不支持的对象会相应地返回 `None` 或 `()`。例如：

      assert get_origin(Dict[str, int]) is dict
      assert get_args(Dict[int, str]) == (int, str)

      assert get_origin(Union[int, str]) is Union
      assert get_args(Union[int, str]) == (int, str)

  3.8 新版功能.

class `typing.``ForwardRef`

  这个类用于字符串前向引用的内部类型展示。例如，`list["SomeClass"]` 被隐式转换为 `list[ForwardRef("SomeClass")]`。该类不能由用户实例化，但可以用于内省工具。

  3.7.4 新版功能.

### 常量

`typing.``TYPE_CHECKING`

  被第三方静态类型检查器假定为 `True` 的特殊常量。在运行时为 `False`。用法如下：

      if TYPE_CHECKING:
          import expensive_mod

      def fun(arg: 'expensive_mod.SomeType') -> None:
          local_var: expensive_mod.AnotherType = other_fun()

  第一个类型注解必须用引号标注，才能把它当作“前向引用”，从而在解释器运行时中隐藏 `expensive_mod` 引用。局部变量的类型注释不会被评估，因此，第二个注解不需要用引号引起来。

  注解

  Python 3.7 或更高版本中使用 `from __future__ import` 时，函数定义时不处理注解， 而是把注解当作字符串存在 `__annotations__` 里，这样就不必为注解使用引号。（详见 PEP 563）。

  3.5.2 新版功能.