"typing" --- 类型提示支持
*************************

3.5 版新加入.

**源码：** Lib/typing.py

備註:

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

======================================================================

这个模块提供对类型提示的运行时支持。最基本的支持包括 "Any" , "Union" ,
"Callable" , "TypeVar" , 和 "Generic" 。关于完整的规范，请参考 **PEP
484** 。关于类型提示的简化介绍，请参考 **PEP 483** 。

下面的函数接收与返回的都是字符串，注解方式如下：

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

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

新的功能频繁地被添加到 "typing" 模块中。typing_extensions 包提供了这些
新功能对旧版本 Python 的向后移植。


相关的 PEP
==========

自从在 **PEP 484** 和 **PEP 483** 中首次引入类型提示以来，一些 PEP 已
经修改和增强了 Python 的类型注释框架。包括:

* **PEP 526**: 变量注解的语法
     *引入* 在函数定义之外标注变量的语法，以及 "ClassVar" 。

* **PEP 544**: Protocol：结构子类型（静态鸭子类型）。
     *引入* "Protocol" 和 "@runtime_checkable" 装饰器。

* **PEP 585**: 标准集合中的类型提示泛型
     *引入* "types.GenericAlias" 和使用标准库类作为 通用类型 的能力。

* **PEP 586**: 文字类型
     *Introducing* "Literal"

* **PEP 589**: TypedDict: 具有固定键集的字典的类型提示
     *引入* "TypedDict"

* **PEP 591**: 为 typing 添加最终限定符
     *引入* "Final" 和 "@final" 装饰器

* **PEP 593**: 灵活的函数和变量注解
     *Introducing* "Annotated"


类型别名
========

把类型赋给别名，就可以定义类型别名。本例中，"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
=======

Use the "NewType()" helper to create distinct types:

   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)

Note that these checks are enforced only by the static type checker.
At runtime, the statement "Derived = NewType('Derived', Base)" will
make "Derived" a callable that immediately returns whatever parameter
you pass it. That means the expression "Derived(some_value)" does not
create a new class or introduce any overhead beyond that of a regular
function call.

更确切地说，在运行时，"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

   async def on_update(value: str) -> None:
       # Body
   callback: Callable[[str], Awaitable[None]] = on_update

无需指定调用签名，用省略号字面量替换类型提示里的参数列表：
"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)

一个泛型可以有任何数量的类型变量。所有种类的 "TypeVar" 都可以作为泛型
的参数:

   from typing import TypeVar, Generic, Sequence

   T = TypeVar('T', contravariant=True)
   B = TypeVar('B', bound=Sequence[bytes], covariant=True)
   S = TypeVar('S', int, str)

   class WeirdTrio(Generic[T, B, 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: Any = None
   a = []          # OK
   a = 2           # OK

   s: 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** 与
   GenericAlias 类型。

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** 与 GenericAlias 类型。

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** 与
   GenericAlias 类型。

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" 对象的相等
   性比较不再依赖顺序。 现在如果有某个参数不为 *hashable*，"Literal"
   对象在相等性比较期间将引发 "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" 进行静态类型检查（可安全地忽略 "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
      S = TypeVar('S', bound=str)  # Can be any subtype of str
      A = TypeVar('A', str, bytes)  # Must be exactly str or bytes

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

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


      def print_capitalized(x: S) -> S:
          """Print x capitalized, and return x."""
          print(x.capitalize())
          return x


      def concatenate(x: A, y: A) -> A:
          """Add two strings or bytes objects together."""
          return x + y

   请注意，类型变量可以是 *被绑定的* ， *被约束的* ，或者两者都不是，
   但不能既是被绑定的 *又是* 被约束的。

   约束类型变量和绑定类型变量在几个重要方面具有不同的语义。使用 *约束*
   类型变量意味着它只能被解析为正好是所给的约束之一:

      a = concatenate('one', 'two')  # Ok, variable 'a' has type 'str'
      b = concatenate(StringSubclass('one'), StringSubclass('two'))  # Inferred type of variable 'b' is 'str',
                                                                     # despite 'StringSubclass' being passed in
      c = concatenate('one', b'two')  # error: type variable 'A' can be either 'str' or 'bytes' in a function call, but not both

   然而，使用一个 *绑定* 类型变量，意味着将使用最具体的类型来解析
   "TypeVar"

      print_capitalized('a string')  # Ok, output has type 'str'

      class StringSubclass(str):
          pass

      print_capitalized(StringSubclass('another string'))  # Ok, output has type 'StringSubclass'
      print_capitalized(45)  # error: int is not a subtype of str

   类型变量可以被绑定到具体类型、抽象类型（ ABC 或 protocol ），甚至是
   类型的联合:

      U = TypeVar('U', bound=str|bytes)  # Can be any subtype of the union str|bytes
      V = TypeVar('V', bound=SupportsAbs)  # Can be anything with an __abs__ method

   绑定类型变量对于注释作为替代构造函数的 "classmethods" 特别有用。在
   下面的例子中（ ©  Raymond Hettinger ），类型变量 "C" 通过使用前向引
   用被绑定到类 "Circle" 。使用这个类型变量来注解类方法
   "with_circumference" ，而不是将返回类型硬编码为 "Circle" ，这意味着
   类型检查器可以正确推断出返回类型，即使该方法是在一个子类上调用的:

      import math

      C = TypeVar('C', bound='Circle')

      class Circle:
          """An abstract circle"""

          def __init__(self, radius: float) -> None:
              self.radius = radius

          # Use a type variable to show that the return type
          # will always be an instance of whatever ``cls`` is
          @classmethod
          def with_circumference(cls: type[C], circumference: float) -> C:
              """Create a circle with the specified circumference"""
              radius = circumference / (math.pi * 2)
              return cls(radius)


      class Tire(Circle):
          """A specialised circle (made out of rubber)"""

          MATERIAL = 'rubber'


      c = Circle.with_circumference(3)  # Ok, variable 'c' has type 'Circle'
      t = Tire.with_circumference(4)  # Ok, variable 't' has type 'Tire' (not 'Circle')

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

   类型变量可以通过传递 "covariant=True" 或 "contravariant=True" 来标
   记协变或反变。 更多细节请参见 **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__" ，给出一个 dict ，将
   字段名映射到字段类型。（字段名在 "_fields" 属性中，默认值在
   "_field_defaults" 属性中，这两者都是 "namedtuple()" 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')

   To allow using this feature with older versions of Python that do
   not support **PEP 526**, "TypedDict" supports two additional
   equivalent syntactic forms:

   * Using a literal "dict" as the second argument:

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

   * Using keyword arguments:

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

   当任何一个键不是有效的 标识符 时，例如因为它们是关键字或包含连字符
   ，也应该使用函数式语法。例子:

      # raises SyntaxError
      class Point2D(TypedDict):
          in: int  # 'in' is a keyword
          x-y: int  # name with hyphens

      # OK, functional syntax
      Point2D = TypedDict('Point2D', {'in': int, 'x-y': int})

   默认情况下，所有的键都必须出现在一个 "TypedDict" 中。 可以通过指定
   总数来重写这一点。用法:

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

      # Alternative syntax
      Point2D = TypedDict('Point2D', {'x': int, 'y': int}, total=False)

   这意味着一个 "Point2D" "TypedDict" 可以省略任何一个键。 类型检查器
   只需要支持一个字面的 "False" 或 "True" 作为 "total" 参数的值。
   "True" 是默认的，它使类主体中定义的所有项目都是必需的。

   一个 "TypedDict" 类型有可能使用基于类的语法从一个或多个其他
   "TypedDict" 类型继承。用法:

      class Point3D(Point2D):
          z: int

   "Point3D" 有三个项目 : "x" , "y" 和 "z" 。 其等价于定义:

      class Point3D(TypedDict):
          x: int
          y: int
          z: int

   "TypedDict" 不能继承于一个非 "TypedDict" 类，其中特别包括 "Generic"
   。例如：

      class X(TypedDict):
          x: int

      class Y(TypedDict):
          y: int

      class Z(object): pass  # A non-TypedDict class

      class XY(X, Y): pass  # OK

      class XZ(X, Z): pass  # raises TypeError

      T = TypeVar('T')
      class XT(X, Generic[T]): pass  # raises TypeError

   A "TypedDict" can be introspected via "__annotations__",
   "__total__", "__required_keys__", and "__optional_keys__".

   __total__

      "Point2D.__total__" gives the value of the "total" argument.
      Example:

         >>> from typing import TypedDict
         >>> class Point2D(TypedDict): pass
         >>> Point2D.__total__
         True
         >>> class Point2D(TypedDict, total=False): pass
         >>> Point2D.__total__
         False
         >>> class Point3D(Point2D): pass
         >>> Point3D.__total__
         True

   __required_keys__

   __optional_keys__

      "Point2D.__required_keys__" 和 "Point2D.__optional_keys__" 分别
      返回 "frozenset" 对象，其中包含必需和非必需键。目前，在同一个
      中声明必需和非必需键的唯一方法是混合继承，用一个 "total" 参数值
      声明一个 "TypedDict" ，然后从另一个 "total" 参数值不同的
      "TypedDict" 中继承它。用法：

         >>> class Point2D(TypedDict, total=False):
         ...     x: int
         ...     y: int
         ...
         >>> class Point3D(Point2D):
         ...     z: int
         ...
         >>> Point3D.__required_keys__ == frozenset({'z'})
         True
         >>> Point3D.__optional_keys__ == frozenset({'x', 'y'})
         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** 和
   GenericAlias 类型。

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** 与
   GenericAlias 类型。

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

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

   3.9 版後已棄用: "builtins.set" 现已支持 "[]"。详见 **PEP 585** 和
   GenericAlias 类型。

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

   "builtins.frozenset" 的泛型版本。

   3.9 版後已棄用: "builtins.frozenset" 现已支持 "[]"。详见 **PEP
   585** 和 GenericAlias 类型。

備註:

  "Tuple" 是一种特殊形式。


"collections" 对应类型
~~~~~~~~~~~~~~~~~~~~~~

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

   "collections.defaultdict" 的泛型版本。

   3.5.2 版新加入.

   3.9 版後已棄用: "collections.defaultdict" 现已支持 "[]"。详见 **PEP
   585** 与 GenericAlias 类型。

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

   "collections.OrderedDict" 的泛型版本。

   3.7.2 版新加入.

   3.9 版後已棄用: "collections.OrderedDict" 现已支持 "[]"。详见 **PEP
   585** 与 GenericAlias 类型。

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

   "collections.ChainMap" 的泛型版本。

   3.5.4 版新加入.

   3.6.1 版新加入.

   3.9 版後已棄用: "collections.ChainMap" 现已支持 "[]"。详见 **PEP
   585** 和 GenericAlias 类型。

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

   "collections.Counter" 的泛型版本。

   3.5.4 版新加入.

   3.6.1 版新加入.

   3.9 版後已棄用: "collections.Counter" 现已支持 "[]"。详见 **PEP
   585** 和 GenericAlias 类型。

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

   "collections.deque" 的泛型版本。

   3.5.4 版新加入.

   3.6.1 版新加入.

   3.9 版後已棄用: "collections.deque" 现已支持 "[]"。详见 **PEP 585**
   和 GenericAlias 类型。


其他具象类型
~~~~~~~~~~~~

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

   泛型类型 "IO[AnyStr]" 及其子类 "TextIO(IO[str])" 与
   "BinaryIO(IO[bytes])" 表示 I/O 流的类型，例如 "open()" 所返回的对象
   。

   Deprecated since version 3.8, will be removed in version 3.12: 这些
   类型也在 "typing.io" 命名空间中，它从未得到类型检查器的支持并将被移
   除。

class typing.Pattern
class typing.Match

   这些类型对应的是从 "re.compile()" 和 "re.match()" 返回的类型。 这些
   类型（及相应的函数）是 "AnyStr" 中的泛型并可通过编写
   "Pattern[str]", "Pattern[bytes]", "Match[str]" 或 "Match[bytes]" 来
   具体指定。

   Deprecated since version 3.8, will be removed in version 3.12: 这些
   类型也在 "typing.re" 命名空间中，它从未得到类型检查器的支持并将被移
   除。

   3.9 版後已棄用: "re" 模块中的 "Pattern" 与 "Match" 类现已支持 "[]"
   。详见 **PEP 585** 与 GenericAlias 类型。

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** 与 GenericAlias 类型。

class typing.ByteString(Sequence[int])

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

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

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

   3.9 版後已棄用: "collections.abc.ByteString" 现已支持 "[]"。详见
   **PEP 585** 与 GenericAlias 类型。

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

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

   3.6.0 版新加入.

   3.9 版後已棄用: "collections.abc.Collection" 现已支持 "[]"。详见
   **PEP 585** 与 GenericAlias 类型。

class typing.Container(Generic[T_co])

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

   3.9 版後已棄用: "collections.abc.Container" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

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

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

   3.9 版後已棄用: "collections.abc.ItemsView" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

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

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

   3.9 版後已棄用: "collections.abc.KeysView" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

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** 和 GenericAlias 类型。

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

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

   3.9 版後已棄用: "collections.abc.MappingView" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

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

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

   3.9 版後已棄用: "collections.abc.MutableMapping" 现已支持 "[]"。详
   见 **PEP 585** 和 GenericAlias 类型。

class typing.MutableSequence(Sequence[T])

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

   3.9 版後已棄用: "collections.abc.MutableSequence" 现已支持 "[]"。详
   见 **PEP 585** 和 GenericAlias 类型。

class typing.MutableSet(AbstractSet[T])

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

   3.9 版後已棄用: "collections.abc.MutableSet" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

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

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

   3.9 版後已棄用: "collections.abc.Sequence" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

class typing.ValuesView(MappingView[VT_co])

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

   3.9 版後已棄用: "collections.abc.ValuesView" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。


"collections.abc" 对应的其他类型
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

class typing.Iterable(Generic[T_co])

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

   3.9 版後已棄用: "collections.abc.Iterable" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

class typing.Iterator(Iterable[T_co])

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

   3.9 版後已棄用: "collections.abc.Iterator" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

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** 和 GenericAlias 类型。

class typing.Hashable

   "collections.abc.Hashable" 的别名。

class typing.Reversible(Iterable[T_co])

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

   3.9 版後已棄用: "collections.abc.Reversible" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

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: Coroutine[list[str], str, int]  # Some coroutine defined elsewhere
      x = c.send('hi')                   # Inferred type of 'x' is list[str]
      async def bar() -> None:
          y = await c                    # Inferred type of 'y' is int

   3.5.3 版新加入.

   3.9 版後已棄用: "collections.abc.Coroutine" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

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** 和 GenericAlias 类型。

class typing.AsyncIterable(Generic[T_co])

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

   3.5.2 版新加入.

   3.9 版後已棄用: "collections.abc.AsyncIterable" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

class typing.AsyncIterator(AsyncIterable[T_co])

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

   3.5.2 版新加入.

   3.9 版後已棄用: "collections.abc.AsyncIterator" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。

class typing.Awaitable(Generic[T_co])

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

   3.5.2 版新加入.

   3.9 版後已棄用: "collections.abc.Awaitable" 现已支持 "[]"。详见
   **PEP 585** 和 GenericAlias 类型。


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

class typing.ContextManager(Generic[T_co])

   "contextlib.AbstractContextManager" 的泛型版本。

   3.5.4 版新加入.

   3.6.0 版新加入.

   3.9 版後已棄用: "contextlib.AbstractContextManager" 现已支持 "[]"。
   详见 **PEP 585** 和 GenericAlias 类型。

class typing.AsyncContextManager(Generic[T_co])

   "contextlib.AbstractAsyncContextManager" 的泛型版本。

   3.5.4 版新加入.

   3.6.2 版新加入.

   3.9 版後已棄用: "contextlib.AbstractAsyncContextManager" 现已支持
   "[]"。详见 **PEP 585** 和 GenericAlias 类型。


协议
----

这些协议由 "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")]"。 这个类不应由用户来实
   例化，但可以由内省工具使用。

   備註:

     **PEP 585** 泛型类型例如 "list["SomeClass"]" 将不会被隐式地转换为
     "list[ForwardRef("SomeClass")]" 因而将不会自动解析为
     "list[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" 引用。局部变量的类型注释不会被评估，因
   此，第二个注解不需要用引号引起来。

   備註:

     使用 "from __future__ import" 时，函数定义时不处理注解， 而是把注
     解当作字符串存在 "__annotations__" 里，这样就不必为注解使用引号。
     （详见 **PEP 563**）。

   3.5.2 版新加入.
