# `typing` --- 支援型別提示

Added in version 3.5.

原始碼：Lib/typing.py

備註

Python runtime 不強制要求函式與變數的型別註釋。他們可以被第三方工具使用，如：型別檢查器、IDE、linter 等。

此模組提供 runtime 型別提示支援。

考虑下面的函数:

    def moon_weight(earth_weight: float) -> str:
        return f'On the moon, you would weigh {earth_weight * 0.166} kilograms.'

函数 `moon_weight` 接受一个预期为 `float` 实例的参数，如 类型提示 `earth_weight: float` 所指明的。 该函数预期返回一个 `str` 实例，如 `-> str` 提示所指明的。

类型提示可以是简单的类比如 `float` 或 `str`，它们也可以更为复杂。 `typing` 模块提供了一套用于更高级类型提示的词汇。

新功能會頻繁的新增至 `typing` 模組中。typing_extensions 套件為這些新功能提供了 backport（向後移植的）版本，提供給舊版本的 Python 使用。

也參考

"型別小抄 (Typing cheat sheet)"

  型別提示的快速預覽（發布於 mypy 的文件中）

mypy 文件的 "型別系統參考資料 (Type System Reference)" 章節

  Python 的加註型別系統是基於 PEPs 進行標準化，所以這個參照 (reference) 應該在多數 Python 型別檢查器中廣為使用。（某些部分依然是特定給 mypy 使用。）

"Python 的靜態型別 (Static Typing)"

  由社群編寫的跨平台型別檢查器文件 (type-checker-agnostic) 詳細描述加註型別系統的功能、實用的加註型別衍伸工具、以及加註型別的最佳實踐 (best practice)。

## 有关 Python 类型系统的规范说明

Python 类型系统最新的规范说明可以在 "Specification for the Python type system" 查看。

## 型別別名

一個型別別名被定義來使用 `type` 陳述式，其建立了 `TypeAliasType` 的實例。在這個範例中，`Vector` 及 `list[float]` 會被當作和靜態型別檢查器一樣同等對待：

    type Vector = list[float]

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

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

型別別名對於簡化複雜的型別簽名 (complex type signature) 非常好用。舉例來說：

    from collections.abc import Sequence

    type ConnectionOptions = dict[str, str]
    type Address = tuple[str, int]
    type 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:
        ...

`type` 陳述式是 Python 3.12 的新功能。為了向後相容性，型別別名可以透過簡單的賦值來建立：

    Vector = list[float]

或是用 `TypeAlias` 標記，讓它明確的表示這是一個型別別名，而非一般的變數賦值：

    from typing import TypeAlias

    Vector: TypeAlias = list[float]

## NewType

使用 `NewType` 輔助工具 (helper) 建立獨特型別：

    from typing import NewType

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

若它是原本型別的子類別，靜態型別檢查器會將其視為一個新的型別。這對於幫助擷取邏輯性錯誤非常有用：

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

    # passes type checking
    user_a = get_user_name(UserId(42351))

    # fails type checking; an int is not a UserId
    user_b = get_user_name(-1)

你依然可以在對於型別 `UserId` 的變數中執行所有 `int` 的操作。這讓你可以在預期接受 `int` 的地方傳遞一個 `UserId`，還能預防你意外使用無效的方法建立一個 `UserId`：

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

注意這只會透過靜態型別檢查器強制檢查。在 runtime 中，陳述式 (statement) `Derived = NewType('Derived', Base)` 會使 `Derived` 成為一個 callable（可呼叫物件），會立即回傳任何你傳遞的引數。這意味著 expression （運算式）`Derived(some_value)` 不會建立一個新的類別或過度引入原有的函式呼叫。

更精確地說，expression `some_value is Derived(some_value)` 在 runtime 永遠為 true。

這會無法建立一個 `Derived` 的子型別：

    from typing import NewType

    UserId = NewType('UserId', int)

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

無論如何，這有辦法基於 '衍生的' `NewType` 建立一個 `NewType`：

    from typing import NewType

    UserId = NewType('UserId', int)

    ProUserId = NewType('ProUserId', UserId)

以及針對 `ProUserId` 的型別檢查會如期運作。

更多細節請見 PEP 484。

備註

請記得使用型別別名是宣告兩種型別是互相相等的。使用 `type Alias = Original` 則會讓靜態型別檢查器在任何情況之下將 `Alias` 視為與 `Original` 完全相等。這當你想把複雜的型別簽名進行簡化時，非常好用。

相反的，`NewType` 宣告一個型別會是另外一種型別的子類別。使用 `Derived = NewType('Derived', Original)` 會使靜態型別檢查器將 `Derived` 視為 `Original` 的子類別，也意味著一個型別為 `Original` 的值，不能被使用在任何預期接收到型別 `Derived` 的值的區域。這當你想用最小的 runtime 成本預防邏輯性錯誤而言，非常有用。

Added in version 3.5.2.

在 3.10 版的變更: 現在的 `NewType` 比起一個函式更像一個類別。因此，比起一般的函式，呼叫 `NewType` 需要額外的 runtime 成本。

在 3.11 版的變更: 呼叫 `NewType` 的效能已經恢復與 Python 3.9 相同的水準。

## 註釋 callable 物件

函式，或者是其他 callable 物件，可以使用 `collections.abc.Callable` 或 `typing.Callable` 進行註釋。 `Callable[[int], str]` 象徵為一個函式，可以接受一個型別為 `int` 的引數，並回傳一個 `str`。

舉例來說：

    from collections.abc import Callable, Awaitable

    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

使用下標語法 (subscription syntax) 時，必須使用到兩個值，分別為引述串列以及回傳類別。引數串列必須為一個型別串列：`ParamSpec`、`Concatenate` 或是一個刪節號 (ellipsis)。回傳類別必為一個單一類別。

若刪節號文字 `...` 被當作引數串列給定，其指出一個具任何、任意參數列表的 callable 會被接受：

    def concat(x: str, y: str) -> str:
        return x + y

    x: Callable[..., str]
    x = str     # OK
    x = concat  # Also OK

`Callable` 不如有可變數量引數的函式、`overloaded functions`、或是僅限關鍵字參數的函式，可以表示複雜簽名。然而，這些簽名可以透過定義一個具有 `__call__()` 方法的 `Protocol` 類別進行表示：

    from collections.abc import Iterable
    from typing import Protocol

    class Combiner(Protocol):
        def __call__(self, *vals: bytes, maxlen: int | None = None) -> list[bytes]: ...

    def batch_proc(data: Iterable[bytes], cb_results: Combiner) -> bytes:
        for item in data:
            ...

    def good_cb(*vals: bytes, maxlen: int | None = None) -> list[bytes]:
        ...
    def bad_cb(*vals: bytes, maxitems: int | None) -> list[bytes]:
        ...

    batch_proc([], good_cb)  # OK
    batch_proc([], bad_cb)   # Error! Argument 2 has incompatible type because of
                             # different name and kind in the callback

Callable 物件可以取用其他 callable 當作引數使用，可以透過 `ParamSpec` 指出他們的參數型別是個別獨立的。另外，如果這個 callable 從其他 callable 新增或刪除引數時，將會使用到 `Concatenate` 運算子。他們可以分別採用 `Callable[ParamSpecVariable, ReturnType]` 以及 `Callable[Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable], ReturnType]` 的形式。

在 3.10 版的變更: `Callable` 現已支援 `ParamSpec` 以及 `Concatenate`。請參閱 PEP 612 閱讀詳細內容。

也參考

`ParamSpec` 以及 `Concatenate` 的文件中，提供範例如何在 `Callable` 中使用。

## 泛型

因為關於物件的型別資訊留存在容器之內，且無法使用通用的方式進行靜態推論 (statically inferred)，許多標準函式庫的容器類別支援以下標來表示容器內預期的元素。

    from collections.abc import Mapping, Sequence

    class Employee: ...

    # Sequence[Employee] indicates that all elements in the sequence
    # must be instances of "Employee".
    # Mapping[str, str] indicates that all keys and all values in the mapping
    # must be strings.
    def notify_by_email(employees: Sequence[Employee],
                        overrides: Mapping[str, str]) -> None: ...

泛型函式及類別可以使用型別參數語法 (type parameter syntax) 進行參數化 (parameterize) ：

    from collections.abc import Sequence

    def first[T](l: Sequence[T]) -> T:  # Function is generic over the TypeVar "T"
        return l[0]

或是直接使用 `TypeVar` 工廠 (factory)：

    from collections.abc import Sequence
    from typing import TypeVar

    U = TypeVar('U')                  # Declare type variable "U"

    def second(l: Sequence[U]) -> U:  # Function is generic over the TypeVar "U"
        return l[1]

在 3.12 版的變更: 在 Python 3.12 中，泛型的語法支援是全新功能。

## 註釋元組 (tuple)

在 Python 大多數的容器當中，加註型別系統認為容器內的所有元素會是相同型別。舉例來說：

    from collections.abc import Mapping

    # Type checker will infer that all elements in ``x`` are meant to be ints
    x: list[int] = []

    # Type checker error: ``list`` only accepts a single type argument:
    y: list[int, str] = [1, 'foo']

    # Type checker will infer that all keys in ``z`` are meant to be strings,
    # and that all values in ``z`` are meant to be either strings or ints
    z: Mapping[str, str | int] = {}

`list` 只接受一個型別引數，所以型別檢查器可能在上述 `y` 賦值 (assignment) 觸發錯誤。類似的範例，`Mapping` 只接受兩個型別引數：第一個引數指出 keys（鍵）的型別；第二個引數指出 values（值）的型別。

然而，與其他多數的 Python 容器不同，在慣用的 (idiomatic) Python 程式碼中，元組可以擁有不完全相同型別的元素是相當常見的。為此，元組在 Python 的加註型別系統中是個特例 (special-cased)。`tuple` 接受任何數量的型別引數：

    # OK: ``x`` is assigned to a tuple of length 1 where the sole element is an int
    x: tuple[int] = (5,)

    # OK: ``y`` is assigned to a tuple of length 2;
    # element 1 is an int, element 2 is a str
    y: tuple[int, str] = (5, "foo")

    # Error: the type annotation indicates a tuple of length 1,
    # but ``z`` has been assigned to a tuple of length 3
    z: tuple[int] = (1, 2, 3)

為了標示一個元組可以為任意長度，且所有元素皆是相同型別 `T`，請使用 `tuple[T, ...]` 進行標示。為了標示一個空元組，請使用 `tuple[()]`。單純使用 `tuple` 作為註釋，會與使用 `tuple[Any, ...]` 是相等的：

    x: tuple[int, ...] = (1, 2)
    # These reassignments are OK: ``tuple[int, ...]`` indicates x can be of any length
    x = (1, 2, 3)
    x = ()
    # This reassignment is an error: all elements in ``x`` must be ints
    x = ("foo", "bar")

    # ``y`` can only ever be assigned to an empty tuple
    y: tuple[()] = ()

    z: tuple = ("foo", "bar")
    # These reassignments are OK: plain ``tuple`` is equivalent to ``tuple[Any, ...]``
    z = (1, 2, 3)
    z = ()

## 類別物件的型別

一個變數被註釋為 `C` 可以接受一個型別為 `C` 的值。相對的，一個變數備註解為 `type[C]` （或 `typing.Type[C]`）可以接受本身為該類別的值 -- 具體來說，他可能會接受 `C` 的類別物件。舉例來說：

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

請記得 `type[C]` 是共變 (covariant) 的：

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

    def make_new_user(user_class: type[User]) -> User:
        # ...
        return user_class()

    make_new_user(User)      # OK
    make_new_user(ProUser)   # Also OK: ``type[ProUser]`` is a subtype of ``type[User]``
    make_new_user(TeamUser)  # Still fine
    make_new_user(User())    # Error: expected ``type[User]`` but got ``User``
    make_new_user(int)       # Error: ``type[int]`` is not a subtype of ``type[User]``

`type` 僅有的合法參數是類別、`Any`、型別變數以及這些型別任意組合成的聯集。舉例來說：

    def new_non_team_user(user_class: type[BasicUser | ProUser]): ...

    new_non_team_user(BasicUser)  # OK
    new_non_team_user(ProUser)    # OK
    new_non_team_user(TeamUser)   # Error: ``type[TeamUser]`` is not a subtype
                                  # of ``type[BasicUser | ProUser]``
    new_non_team_user(User)       # Also an error

`type[Any]` 等價於 `type` ，其為 Python metaclass 階層結構 (hierachy)。

## 使用者定義泛型型別

一個使用者定義的類別可以被定義成一個泛型類別。

    from logging import Logger

    class LoggedVar[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)

這個語法指出類別 `LoggedVar` 透過一個單一的 型別變數 `T` 進行參數化 (parameterised)。這使得 `T` 在類別中有效的成為型別。

泛型類別隱性繼承了 `Generic`。為了相容 Python 3.11 及更早版本，也可以明確的繼承 `Generic` 並指出是一個泛型類別：

    from typing import TypeVar, Generic

    T = TypeVar('T')

    class LoggedVar(Generic[T]):
        ...

泛型類別有 `__class_getitem__()` 方法，其意味著可以在 runtime 進行參數化（如下述的 `LoggedVar[int]`）：

    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

    class WeirdTrio[T, B: Sequence[bytes], S: (int, str)]:
        ...

    OldT = TypeVar('OldT', contravariant=True)
    OldB = TypeVar('OldB', bound=Sequence[bytes], covariant=True)
    OldS = TypeVar('OldS', int, str)

    class OldWeirdTrio(Generic[OldT, OldB, OldS]):
        ...

`Generic` 的每個型別變數引數必不相同。因此以下是無效的：

    from typing import TypeVar, Generic
    ...

    class Pair[M, M]:  # SyntaxError
        ...

    T = TypeVar('T')

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

泛型類別亦可以繼承其他類別：

    from collections.abc import Sized

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

當繼承泛型類別時，部份的型別參數可固定：

    from collections.abc import Mapping

    class MyDict[T](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

    type Response[S] = Iterable[S] | int

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

    type Vec[T] = Iterable[tuple[T, T]]

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

為了向後相容性，泛型型別別名可以透過簡單的賦值來建立：

    from collections.abc import Iterable
    from typing import TypeVar

    S = TypeVar("S")
    Response = Iterable[S] | int

在 3.7 版的變更: `Generic` 不再是一個自訂的 metaclass。

在 3.12 版的變更: 在版本 3.12 新增了泛型及型別別名的語法支援。在之前的版本中，泛型類別必須顯性繼承 `Generic` 或是包含一個型別變數在基底類別 (base) 當中。

使用者定義的參數運算式 (parameter expression) 泛型一樣有支援，透過 `[**P]` 格式的參數規格變數來進行表示。對於上述作為參數規格變數的型別變數，將持續被型別模組視為一個特定的型別變數。對此，其中一個例外是一個型別列表可以替代 `ParamSpec`：

    >>> class Z[T, **P]: ...  # T is a TypeVar; P is a ParamSpec
    ...
    >>> Z[int, [dict, float]]
    __main__.Z[int, [dict, float]]

具有 `ParamSpec` 的泛型類別可以透過顯性繼承 `Generic` 進行建立。在這種情況下，不需要使用 `**`：

    from typing import ParamSpec, Generic

    P = ParamSpec('P')

    class Z(Generic[P]):
        ...

另外一個 `TypeVar` 以及 `ParamSpec` 之間的差異是，基於美觀因素，只有一個參數規格變數的泛型可以接受如 `X[[Type1, Type2, ...]]` 以及 `X[Type1, Type2, ...]` 的參數列表。在內部中，後者會被轉換為前者，所以在下方的範例中為相等的：

    >>> class X[**P]: ...
    ...
    >>> X[int, str]
    __main__.X[[int, str]]
    >>> X[[int, str]]
    __main__.X[[int, str]]

請記得，具有 `ParamSpec` 的泛型在某些情況下替換之後可能不會有正確的 `__parameters__`，因為參數規格主要還是用於靜態型別檢查。

在 3.10 版的變更: `Generic` 現在可以透過參數運算式來進行參數化。詳細內容請見 `ParamSpec` 以及 PEP 612。

一個使用者定義的泛型類別可以將 ABC 作為他們的基底類別，且不會有 metaclass 衝突。泛型的 metaclass 則不支援。參數化泛型的輸出將被存為快取，而在型別模組中多數的型別皆為 hashable 且可以比較相等性。

## `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:
        # Passes type checking; 'item' could be any type,
        # and that type might have a 'bar' method
        item.bar()
        ...

請注意，當賦予型別為 `Any` 的值更精確的型別時，將不會執行任何型別檢查。舉例來說，靜態型別檢查器不會在 runtime 中，將 `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` 被當作一個緊急出口 (escape hatch)使用。

`Any` 的行為對比 `object` 的行為。與 `Any` 相似，所有的型別會作為 `object` 的子型別。然而，不像 `Any`，反之不亦然：`object` 並不是一個其他型別的子型別。

這意味著當一個值的型別為 `object` 時，型別檢查器會拒絕幾乎所有的操作，並將賦予這個值到一個特定型別變數（或是當作回傳值使用）視為一個型別錯誤。舉例來說：

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

    def hash_b(item: Any) -> int:
        # Passes type checking
        item.magic()
        ...

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

    # Passes type checking, since Any is compatible with all types
    hash_b(42)
    hash_b("foo")

使用 `object` ，將指出在型別安全 (typesafe) 的習慣之下一個值可以為任意型別。使用 `Any`，將指出這個值是個動態型別。

## 標稱 (nominal) 子型別 vs 結構子型別

最初 PEP 484 定義 Python 靜態型別系統使用標稱子型別。這意味著只有 `A` 為 `B` 的子類別時，`A` 才被允許使用在預期是類別 `B` 出現的地方。

這個需求之前也被運用在抽象基底類別，例如 `Iterable`。這種方式的問題在於，一個類別需要顯式的標記來支援他們，這並不符合 Python 風格，也不像一個常見的慣用動態型別 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` 建立子型別時，使用者可以定義新的協定並充份發揮結構子型別的優勢（請見下方範例）。

## 模組內容

模組 `typing` 定義了下列的類別、函式以及裝飾器。

### 特別型別原語 (primitive)

#### 特別型別

這些可以在註釋中做為型別。他們並不支援 `[]` 的下標使用。

typing.Any

  特別型別，指出一個不受約束 (unconstrained) 的型別。

  - 所有型別皆與 `Any` 相容。

  - `Any` 相容於所有型別。

  在 3.11 版的變更: `Any` 可以作為一個基礎類別。這對於在任何地方使用鴨子型別或是高度動態的型別，避免型別檢查器的錯誤是非常有用的。

typing.AnyStr

  一個不受約束的型別變數。

  定義：

      AnyStr = TypeVar('AnyStr', str, bytes)

  `AnyStr` 是對於函式有用的，他可以接受 `str` 或 `bytes` 引數但不可以將此兩種混合。

  舉例來說：

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

      concat("foo", "bar")    # OK, output has type 'str'
      concat(b"foo", b"bar")  # OK, output has type 'bytes'
      concat("foo", b"bar")   # Error, cannot mix str and bytes

  請注意，儘管他的名稱相近，`AnyStr` 與 `Any` 型別無關，更不代表是「任何字串」的意思。尤其，`AnyStr` 與 `str | bytes` 兩者不同且具有不同的使用情境：

      # Invalid use of AnyStr:
      # The type variable is used only once in the function signature,
      # so cannot be "solved" by the type checker
      def greet_bad(cond: bool) -> AnyStr:
          return "hi there!" if cond else b"greetings!"

      # The better way of annotating this function:
      def greet_proper(cond: bool) -> str | bytes:
          return "hi there!" if cond else b"greetings!"

typing.LiteralString

  特別型別，只包含文本字串。

  任何文本字串都相容於 `LiteralString`，對於另一個 `LiteralString` 亦是如此。然而，若是一個型別僅為 `str` 的物件則不相容。一個字串若是透過組合多個 `LiteralString` 型別的物件建立，則此字串也可以視為 `LiteralString`。

  舉例來說：

      def run_query(sql: LiteralString) -> None:
          ...

      def caller(arbitrary_string: str, literal_string: LiteralString) -> None:
          run_query("SELECT * FROM students")  # OK
          run_query(literal_string)  # OK
          run_query("SELECT * FROM " + literal_string)  # OK
          run_query(arbitrary_string)  # type checker error
          run_query(  # type checker error
              f"SELECT * FROM students WHERE name = {arbitrary_string}"
          )

  `LiteralString` 對於敏感的 API 來說是有用的，其中任意的使用者產生的字串可能會產生問題。舉例來說，上面兩個案例中產生的型別檢查器錯誤是脆弱的且容易受到 SQL 注入攻擊。

  更多細節請見 PEP 675。

  Added in version 3.11.

typing.Never

  底部型別 (bottom type)，為一個型別但沒有任何的成員。

  這可以被用來定義一個不應被呼叫的函式，或是一個不會回傳的函式：

      from typing import Never

      def never_call_me(arg: Never) -> None:
          pass

      def int_or_str(arg: int | str) -> None:
          never_call_me(arg)  # type checker error
          match arg:
              case int():
                  print("It's an int")
              case str():
                  print("It's a str")
              case _:
                  never_call_me(arg)  # OK, arg is of type Never

  Added in version 3.11: 在舊的 Python 版本當中，`NoReturn` 可以用來當作一樣的概念使用。新增 `Never` 之後，則讓這個含義變得更為明確。

typing.NoReturn

  特別型別，指出一個永不回傳的函式。

  舉例來說：

      from typing import NoReturn

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

  `NoReturn` 可以用來作為一個底部型別，一個沒有值的型別。從 Python 3.11 開始，型別 `Never` 應該改用這個概念。型別檢查器應該將這兩種型別視為相等的。

  Added in version 3.6.2.

typing.Self

  特別型別，用來表示當前類別之內 (enclosed class)。

  舉例來說：

      from typing import Self, reveal_type

      class Foo:
          def return_self(self) -> Self:
              ...
              return self

      class SubclassOfFoo(Foo): pass

      reveal_type(Foo().return_self())  # Revealed type is "Foo"
      reveal_type(SubclassOfFoo().return_self())  # Revealed type is "SubclassOfFoo"

  這個註釋在語意上相等於下列內容，且形式更為簡潔：

      from typing import TypeVar

      Self = TypeVar("Self", bound="Foo")

      class Foo:
          def return_self(self: Self) -> Self:
              ...
              return self

  一般來說，如果某個東西回傳 `self` 如上方的範例所示，你則應該使用 `Self` 做為回傳值的註釋。若 `Foo.return_self` 被註釋為回傳 `"Foo"`，則型別檢查器應該推論這個從 `SubclassOfFoo.return_self` 回傳的物件為 `Foo` 型別，而並非回傳 `SubclassOfFoo` 型別。

  其他常見的使用案例包含：

  - `classmethod` 被用來作為替代的建構函式 (constructor) 並回傳 `cls` 參數的實例。

  - 註釋一個回傳自己的 `__enter__()` 方法。

  當類別被子類別化時，若方法不保證回傳一個子類別的實例，你不應該使用 `Self` 作為回傳註釋：

      class Eggs:
          # Self would be an incorrect return annotation here,
          # as the object returned is always an instance of Eggs,
          # even in subclasses
          def returns_eggs(self) -> "Eggs":
              return Eggs()

  更多細節請見 PEP 673。

  Added in version 3.11.

typing.TypeAlias

  做為明確宣告一個型別別名 的特別註釋。

  舉例來說：

      from typing import TypeAlias

      Factors: TypeAlias = list[int]

  `TypeAlias` 在舊的 Python 版本中特別有用，其註釋別名可以用來進行傳遞參照 (forward reference)，因為對於型別檢查器來說，分辨這些別名與一般的變數賦值相當困難：

      from typing import Generic, TypeAlias, TypeVar

      T = TypeVar("T")

      # "Box" does not exist yet,
      # so we have to use quotes for the forward reference on Python <3.12.
      # Using ``TypeAlias`` tells the type checker that this is a type alias declaration,
      # not a variable assignment to a string.
      BoxOfStrings: TypeAlias = "Box[str]"

      class Box(Generic[T]):
          @classmethod
          def make_box_of_strings(cls) -> BoxOfStrings: ...

  更多細節請見 PEP 613。

  Added in version 3.10.

  在 3.12 版之後被棄用: `TypeAlias` 被棄用，請改用 `type` 陳述式來建立 `TypeAliasType` 的實例，其自然可以支援傳遞參照的使用。請注意，雖然 `TypeAlias` 以及 `TypeAliasType` 提供相似的用途且具有相似的名稱，他們是不同的，且後者不是前者的型別。現在還沒有移除 `TypeAlias` 的計畫，但鼓勵使用者們遷移 (migrate) 至 `type` 陳述式。

#### 特殊形式

这些内容在注解中可以视为类型，且都支持下标用法（`[]`），但每个都有唯一的语法。

typing.Union

  联合类型； `Union[X, Y]` 等价于 `X | Y` ，意味着满足 X 或 Y 之一。

  要定义一个联合类型，可以使用类似 `Union[int, str]` 或简写 `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] == int | str

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

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

  - 不可创建 `Union` 的子类或实例。

  - 你不能寫成 `Union[X][Y]`。

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

  在 3.10 版的變更: 联合类型现在可以写成 `X | Y`。 参见 联合类型表达式。

typing.Optional

  `Optional[X]` 等价于 `X | None` （或 `Union[X, None]` ） 。

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

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

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

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

  在 3.10 版的變更: 可选参数现在可以写成 `X | None`。 参见 联合类型表达式。

typing.Concatenate

  特殊形式，用于注解高阶函数。

  `Concatenate` 可用于与 Callable 和 `ParamSpec` 连用来注解高阶可调用对象，该可象可以添加、移除或转换另一个可调用对象的形参。 使用形式为 `Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]`。 `Concatenate` 目前仅可用作传给 Callable 的第一个参数。传给 `Concatenate` 的最后一个形参必须是 `ParamSpec` 或省略号（ `...` ）。

  例如，为了注释一个装饰器 `with_lock`，它为被装饰的函数提供了 `threading.Lock`，`Concatenate` 可以用来表示 `with_lock` 期望一个可调用对象，该对象接收一个 `Lock` 作为第一个参数，并返回一个具有不同类型签名的可调用对象。 在这种情况下，`ParamSpec` 表示返回的可调用对象的参数类型取决于被传入的可调用程序的参数类型:

      from collections.abc import Callable
      from threading import Lock
      from typing import Concatenate

      # Use this lock to ensure that only one thread is executing a function
      # at any time.
      my_lock = Lock()

      def with_lock[**P, R](f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]:
          '''A type-safe decorator which provides a lock.'''
          def inner(*args: P.args, **kwargs: P.kwargs) -> R:
              # Provide the lock as the first argument.
              return f(my_lock, *args, **kwargs)
          return inner

      @with_lock
      def sum_threadsafe(lock: Lock, numbers: list[float]) -> float:
          '''Add a list of numbers together in a thread-safe manner.'''
          with lock:
              return sum(numbers)

      # We don't need to pass in the lock ourselves thanks to the decorator.
      sum_threadsafe([1.1, 2.2, 3.3])

  Added in version 3.10.

  也參考

  - PEP 612 -- 参数规范变量（引入 `ParamSpec` 和 `Concatenate` 的 PEP）

  - `ParamSpec`

  - 註釋 callable 物件

typing.Literal

  特殊类型注解形式，用于定义“字面值类型”。

  `Literal` 可以用来向类型检查器说明被注解的对象具有与所提供的字面量之一相同的值。

  舉例來說：

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

      type 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 。

  Added in version 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

  Added in version 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。

  Added in version 3.8.

typing.Required

  特殊类型注解构造，用于标记 `TypedDict` 键为必填项。

  主要用於 `total=False` 的 TypedDict。更多細節請見 `TypedDict` 與 PEP 655。

  Added in version 3.11.

typing.NotRequired

  特殊类型注解构造，用于标记 `TypedDict` 键为可能不存在的键。

  更多細節請見 `TypedDict` 與 PEP 655。

  Added in version 3.11.

typing.Annotated

  特殊类型注解形式，用于向注解添加特定于上下文的元数据。

  使用注解 `Annotated[T, x]` 将元数据 `x` 添加到给定类型 `T` 。使用 `Annotated` 添加的元数据可以被静态分析工具使用，也可以在运行时使用。在运行时使用的情况下，元数据存储在 `__metadata__` 属性中。

  如果库或工具遇到注解 `Annotated[T, x]` ，并且没有针对这一元数据的特殊处理逻辑，则应该忽略该元数据，简单地将注解视为 `T` 。因此， `Annotated` 对于希望将注解用于 Python 的静态类型注解系统之外的目的的代码很有用。

  使用 `Annotated[T, x]` 作为注解仍然允许对 `T` 进行静态类型检查，因为类型检查器将简单地忽略元数据 `x` 。因此，`Annotated` 不同于 `@no_type_check` 装饰器，后者虽然也可以用于在类型注解系统范围之外添加注解，但是会完全禁用对函数或类的类型检查。

  具体解释元数据的方式由遇到 `Annotated` 注解的工具或库来负责。遇到 `Annotated` 类型的工具或库可以扫描元数据的各个元素以确定其是否有意处理（比如使用 `isinstance()` ）。

  Annotated[<type>, <metadata>]

  以下示例演示在进行区间范围分析时使用 `Annotated` 将元数据添加到类型注解的方法：

      @dataclass
      class ValueRange:
          lo: int
          hi: int

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

  语法细节：

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

  - 可提供多个元数据的元素（ `Annotated` 支持可变参数）：

        @dataclass
        class ctype:
            kind: str

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

    由处理注解的工具决定是否允许向一个注解中添加多个元数据元素，以及如何合并这些注解。

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

  - 元数据元素的顺序会被保留，且影响等价检查：

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

  - 嵌套的 `Annotated` 类型会被展平。元数据元素从最内层的注解开始依次展开：

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

  - 元数据中的重复元素不会被移除：

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

  - `Annotated` 可以与嵌套别名和泛型别名一起使用：

        @dataclass
        class MaxLen:
            value: int

        type Vec[T] = Annotated[list[tuple[T, T]], MaxLen(10)]

        # When used in a type annotation, a type checker will treat "V" the same as
        # ``Annotated[list[tuple[int, int]], MaxLen(10)]``:
        type V = Vec[int]

  - `Annotated` 不能与已解包的 `TypeVarTuple` 一起使用:

        type Variadic[*Ts] = Annotated[*Ts, Ann1]  # NOT valid

    這會等價於：

        Annotated[T1, T2, T3, ..., Ann1]

    其中 `T1` 、 `T2` 等都是 `TypeVars` 。这种写法无效：应当只有一个类型被传递给 Annotated。

  - 默认情况下， `get_type_hints()` 会去除注解中的元数据。传入 `include_extras=True` 可以保留元数据：

        >>> from typing import Annotated, get_type_hints
        >>> def func(x: Annotated[int, "metadata"]) -> None: pass
        ...
        >>> get_type_hints(func)
        {'x': <class 'int'>, 'return': <class 'NoneType'>}
        >>> get_type_hints(func, include_extras=True)
        {'x': typing.Annotated[int, 'metadata'], 'return': <class 'NoneType'>}

  - 在运行时，与特定 `Annotated` 类型相关联的元数据可通过 `__metadata__` 属性来获取：

        >>> from typing import Annotated
        >>> X = Annotated[int, "very", "important", "metadata"]
        >>> X
        typing.Annotated[int, 'very', 'important', 'metadata']
        >>> X.__metadata__
        ('very', 'important', 'metadata')

  也參考

  PEP 593 - 灵活的函数与变量标注

    该 PEP 将 `Annotated` 引入到标准库中。

  Added in version 3.9.

typing.TypeGuard

  用于标记用户自定义类型防护函数的特殊类型构造。

  `TypeGuard` 可被用于标注用户自定义类型保护函数的返回类型。 `TypeGuard` 只接受单独的类型参数。 在运行时，以这种方式标记的函数应当返回一个布尔值。

  `TypeGuard` 旨在使 类型收窄 受益——这是静态类型检查器用以确定表达式在代码流中的较精确类型的一种技术。通常，类型收窄是以分析条件代码流并将收窄应用于一个代码块来完成的，涉及到的条件表达式有时即被称为“type guard”。

      def is_str(val: str | float):
          # "isinstance" type guard
          if isinstance(val, str):
              # Type of ``val`` is narrowed to ``str``
              ...
          else:
              # Else, type of ``val`` is narrowed to ``float``.
              ...

  定义一个布尔函数作为 type guard 有时会很方便，此时应使用 `TypeGuard[...]` 作为其返回类型以提醒静态类型检查器注意这一意图。

  `-> TypeGuard` 告诉静态类型检查器，某函数：

  1. 返回一个布尔值。

  2. 如果返回值是 `True`，那么其参数的类型是 `TypeGuard` 内的类型。

  舉例來說：

      def is_str_list(val: list[object]) -> TypeGuard[list[str]]:
          '''Determines whether all objects in the list are strings'''
          return all(isinstance(x, str) for x in val)

      def func1(val: list[object]):
          if is_str_list(val):
              # Type of ``val`` is narrowed to ``list[str]``.
              print(" ".join(val))
          else:
              # Type of ``val`` remains as ``list[object]``.
              print("Not a list of strings!")

  如果 `is_str_list` 是一个类或实例方法，那么 `TypeGuard` 中的类型映射到 `cls` 或 `self` 之后的第二个参数的类型。

  简而言之，`def foo(arg: TypeA) -> TypeGuard[TypeB]: ...` 形式的意思是：如果 `foo(arg)` 返回 `True`，那么 `arg` 将把 `TypeA` 缩小为 `TypeB`。

  備註

  `TypeB` 无需为 `TypeA` 的缩小形式 -- 它甚至可以是扩大形式。 主要原因是允许像把 `list[object]` 缩小到 `list[str]` 这样的事情，即使后者不是前者的一个子类型，因为 `list` 是不变的。 编写类型安全的类型防护的责任留给了用户。

  `TypeGuard` 也适用于类型变量。 详情参见 PEP 647。

  Added in version 3.10.

typing.Unpack

  在概念上将对象标记为已解包的类型运算符。

  例如，在一个 类型变量元组 上使用解包运算符 `*` 就等价于使用 `Unpack` 来将该类型变量元组标记为已被解包:

      Ts = TypeVarTuple('Ts')
      tup: tuple[*Ts]
      # Effectively does:
      tup: tuple[Unpack[Ts]]

  实际上，`Unpack` 在 `typing.TypeVarTuple` 和 `builtins.tuple` 类型的上下文中可以和 `*` 互换使用。 你可能会看到 `Unpack` 在较旧版本的 Python 中被显式地使用，这时 `*` 在特定场合则是无法使用的:

      # In older versions of Python, TypeVarTuple and Unpack
      # are located in the `typing_extensions` backports package.
      from typing_extensions import TypeVarTuple, Unpack

      Ts = TypeVarTuple('Ts')
      tup: tuple[*Ts]         # Syntax error on Python <= 3.10!
      tup: tuple[Unpack[Ts]]  # Semantically equivalent, and backwards-compatible

  `Unpack` 也可以与 `typing.TypedDict` 一起使用以便在函数签名中对 `**kwargs` 进行类型标注:

      from typing import TypedDict, Unpack

      class Movie(TypedDict):
          name: str
          year: int

      # This function expects two keyword arguments - `name` of type `str`
      # and `year` of type `int`.
      def foo(**kwargs: Unpack[Movie]): ...

  请参阅 PEP 692 了解将 `Unpack` 用于 `**kwargs` 类型标注的更多细节。

  Added in version 3.11.

#### 构造泛型类型与类型别名

下列类不应被直接用作标注。 它们的设计目标是作为创建泛型类型和类型别名的构件。

这些对象可通过特殊语法 (类型形参列表 和 `type` 语句) 来创建。 为了与 Python 3.11 及更早版本的兼容性，它们也可不用专门的语法来创建，如下文所述。

class typing.Generic

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

  泛型类型通常是通过在类名后添加一个类型形参列表来声明的:

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

  这样的类将隐式地继承自 `Generic`。 对于该语法的运行语义的讨论参见 语言参考。

  该类的用法如下：

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

  此处函数名之后的圆括号是表示 泛型函数。

  为了保持向下兼容性，泛型类也可通过显式地继承自 `Generic` 来声明。 在此情况下，类型形参必须单独声明:

      KT = TypeVar('KT')
      VT = TypeVar('VT')

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

class typing.TypeVar(name, *constraints, bound=None, covariant=False, contravariant=False, infer_variance=False)

  类型变量。

  构造类型变量的推荐方式是使用针对 泛型函数, 泛型类 和 泛型类型别名 的专门语法:

      class Sequence[T]:  # T is a TypeVar
          ...

  此语法也可被用于创建绑定和带约束的类型变量:

      class StrSequence[S: str]:  # S is a TypeVar bound to str
          ...

      class StrOrBytesSequence[A: (str, bytes)]:  # A is a TypeVar constrained to str or bytes
          ...

  不过，如有需要，也可通过手动方式来构造可重用的类型变量，就像这样:

      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[T](x: T, n: int) -> Sequence[T]:
          """Return a list containing n references to x."""
          return [x]*n

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

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

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

  类型变量的种类是在其通过 类型形参语法 创建时或是在传入 `infer_variance=True` 时由类型检查器推断得到的。 手动创建的类型变量可通过传入 `covariant=True` 或 `contravariant=True` 被显式地标记为 covariant 或 contravariant。 在默认情况下，手动创建的类型变量为 invariant。 请参阅 PEP 484 和 PEP 695 了解更多细节。

  绑定类型变量和约束类型变量在几个重要方面具有不同的主义。 使用 绑定 类型变量意味着 `TypeVar` 将尽可能使用最为专属的类型来解析:

      x = print_capitalized('a string')
      reveal_type(x)  # revealed type is str

      class StringSubclass(str):
          pass

      y = print_capitalized(StringSubclass('another string'))
      reveal_type(y)  # revealed type is StringSubclass

      z = print_capitalized(45)  # error: int is not a subtype of str

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

      # Can be anything with an __abs__ method
      def print_abs[T: SupportsAbs](arg: T) -> None:
          print("Absolute value:", abs(arg))

      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

  但是，如果使用 约束 类型变量，则意味着 `TypeVar` 只能被解析为恰好是给定的约束之一:

      a = concatenate('one', 'two')
      reveal_type(a)  # revealed type is str

      b = concatenate(StringSubclass('one'), StringSubclass('two'))
      reveal_type(b)  # revealed type 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

  在运行时，`isinstance(x, T)` 将引发 `TypeError`。

  __name__

    类型变量的名称。

  __covariant__

    类型变量是否已被显式地标记为 covariant。

  __contravariant__

    类型变量是否已被显式地标记为 contravariant。

  __infer_variance__

    类型变量的种类是否应由类型检查器来推断。

    Added in version 3.12.

  __bound__

    类型变量的绑定，如果有的话。

    在 3.12 版的變更: 对于通过 类型形参语法 创建的类型变量，只有在属性被访问的时候才会对绑定求值，而不是在类型变量被创建的时候 (参见 惰性求值)。

  __constraints__

    一个包含对类型变量的约束的元组，如果有的话。A tuple containing the constraints of the type variable, if any.

    在 3.12 版的變更: 对于通过 类型形参语法 创建的类型变量，只有在属性被访问的时候才会对约束求值，而不是在类型变量被创建的时候 (参见 惰性求值)。

  在 3.12 版的變更: 类型变量现在可以通过使用 PEP 695 引入的 类型形参 语法来声明。 增加了 `infer_variance` 形参。

class typing.TypeVarTuple(name)

  类型变量元组。 一种启用了 variadic 泛型的专属 类型变量 形式。

  类型变量元组可以通过在 类型形参列表 中使用名称前的单个星号 (`*`) 来声明:

      def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]:
          return (*tup[1:], tup[0])

  或者通过显式地发起调用 `TypeVarTuple` 构造器:

      T = TypeVar("T")
      Ts = TypeVarTuple("Ts")

      def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]:
          return (*tup[1:], tup[0])

  一个普通类型变量将启用单个类型的形参化。 作为对比，一个类型变量元组通过将 任意 数量的类型变量封包在一个元组中来允许 任意 数量类型的形参化。 例如:

      # T is bound to int, Ts is bound to ()
      # Return value is (1,), which has type tuple[int]
      move_first_element_to_last(tup=(1,))

      # T is bound to int, Ts is bound to (str,)
      # Return value is ('spam', 1), which has type tuple[str, int]
      move_first_element_to_last(tup=(1, 'spam'))

      # T is bound to int, Ts is bound to (str, float)
      # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int]
      move_first_element_to_last(tup=(1, 'spam', 3.0))

      # This fails to type check (and fails at runtime)
      # because tuple[()] is not compatible with tuple[T, *Ts]
      # (at least one element is required)
      move_first_element_to_last(tup=())

  请注意解包运算符 `*` 在 `tuple[T, *Ts]` 中的使用。 在概念上，你可以将 `Ts` 当作一个由类型变量组成的元组 `(T1, T2, ...)`。 那么 `tuple[T, *Ts]` 就将变为 `tuple[T, *(T1, T2, ...)]`，这等价于 `tuple[T, T1, T2, ...]`。 （请注意在旧版本 Python 中，你可能会看到改用 `Unpack` 的写法，如 `Unpack[Ts]`。）

  类型变量元组 总是 要被解包。 这有助于区分类型变量元组和普通类型变量:

      x: Ts          # Not valid
      x: tuple[Ts]   # Not valid
      x: tuple[*Ts]  # The correct way to do it

  类型变量元组可被用在与普通类型变量相同的上下文中。 例如，在类定义、参数和返回类型中:

      class Array[*Shape]:
          def __getitem__(self, key: tuple[*Shape]) -> float: ...
          def __abs__(self) -> "Array[*Shape]": ...
          def get_shape(self) -> tuple[*Shape]: ...

  类型变量元组可以很好地与普通类型变量结合在一起：

      class Array[DType, *Shape]:  # This is fine
          pass

      class Array2[*Shape, DType]:  # This would also be fine
          pass

      class Height: ...
      class Width: ...

      float_array_1d: Array[float, Height] = Array()     # Totally fine
      int_array_2d: Array[int, Height, Width] = Array()  # Yup, fine too

  但是，请注意在一个类型参数或类型形参列表中最多只能有一个类型变量元组:

      x: tuple[*Ts, *Ts]            # Not valid
      class Array[*Shape, *Shape]:  # Not valid
          pass

  最后，一个已解包的类型变量元组可以被用作 `*args` 的类型标注:

      def call_soon[*Ts](
               callback: Callable[[*Ts], None],
               *args: *Ts
      ) -> None:
          ...
          callback(*args)

  相比非解包的 `*args` 标注 —— 例如 `*args: int`，它将指明 所有 参数均为 `int` —— `*args: *Ts` 启用了对 `*args` 中 单个 参数的类型的引用。 在此，这允许我们确保传入 `call_soon` 的 `*args` 的类型与 `callback` 的（位置）参数的类型相匹配。

  关于类型变量元组的更多细节，请参见 PEP 646。

  __name__

    类型变量元组的名称。

  Added in version 3.11.

  在 3.12 版的變更: 类型变量元组现在可以使用 PEP 695 所引入的 类型形参 语法来声明。

class typing.ParamSpec(name, *, bound=None, covariant=False, contravariant=False)

  形参专属变量。 类型变量 的一个专用版本。

  In 类型形参列表，形参规格可以使用两个星号 (`**`) 来声明:

      type IntFunc[**P] = Callable[P, int]

  为了保持与 Python 3.11 及更早版本的兼容性，`ParamSpec` 对象也可以这样创建:

      P = ParamSpec('P')

  参数规范变量的存在主要是为了使静态类型检查器受益。 它们被用来将一个可调用对象的参数类型转发给另一个可调用对象的参数类型——这种模式通常出现在高阶函数和装饰器中。 它们只有在 `Concatenate` 中使用时才有效，或者作为 `Callable` 的第一个参数，或者作为用户定义的泛型的参数。 参见 `Generic` 以了解更多关于泛型的信息。

  例如，为了给一个函数添加基本的日志记录，我们可以创建一个装饰器 `add_logging` 来记录函数调用。 参数规范变量告诉类型检查器，传入装饰器的可调用对象和由其返回的新可调用对象有相互依赖的类型参数:

      from collections.abc import Callable
      import logging

      def add_logging[T, **P](f: Callable[P, T]) -> Callable[P, T]:
          '''A type-safe decorator to add logging to a function.'''
          def inner(*args: P.args, **kwargs: P.kwargs) -> T:
              logging.info(f'{f.__name__} was called')
              return f(*args, **kwargs)
          return inner

      @add_logging
      def add_two(x: float, y: float) -> float:
          '''Add two numbers together.'''
          return x + y

  如果没有 `ParamSpec`，以前注释这个的最简单的方法是使用一个 `TypeVar` 与绑定 `Callable[..., Any]`。

  1. 类型检查器不能对 `inner` 函数进行类型检查，因为 `*args` 和 `**kwargs` 的类型必须是 `Any`。

  2. `cast()` 在返回 `inner` 函数时，可能需要在 `add_logging` 装饰器的主体中进行，或者必须告诉静态类型检查器忽略 `return inner`。

  args
  kwargs

    由于 `ParamSpec` 同时捕获了位置参数和关键字参数，`P.args` 和 `P.kwargs` 可以用来将 `ParamSpec` 分割成其组成部分。 `P.args` 代表给定调用中的位置参数的元组，只能用于注释 `*args`。 `P.kwargs` 代表给定调用中的关键字参数到其值的映射，只能用于注释 `**kwargs`。在运行时，`P.args` 和 `P.kwargs` 分别是 `ParamSpecArgs` 和 `ParamSpecKwargs` 的实例。

  __name__

    形参规格的名称。

  用 `covariant=True` 或 `contravariant=True` 创建的参数规范变量可以用来声明协变或逆变泛型类型。 参数 `bound` 也被接受，类似于 `TypeVar`。 然而这些关键字的实际语义还有待决定。

  Added in version 3.10.

  在 3.12 版的變更: 形参说明现在可以使用 PEP 695 所引入的 类型形参 语法来声明。

  備註

  只有在全局范围内定义的参数规范变量可以被 pickle。

  也參考

  - PEP 612 -- 参数规范变量（引入 `ParamSpec` 和 `Concatenate` 的 PEP）

  - `Concatenate`

  - 註釋 callable 物件

typing.ParamSpecArgs
typing.ParamSpecKwargs

  `ParamSpec`的参数和关键字参数属性。``ParamSpec`` 的 `P.args` 属性是 `ParamSpecArgs` 的一个实例，`P.kwargs` 是 `ParamSpecKwargs` 的一个实例。 它们的目的是用于运行时内部检查的，对静态类型检查器没有特殊意义。

  在这些对象中的任何一个上调用 `get_origin()` 将返回原始的 `ParamSpec`:

      >>> from typing import ParamSpec, get_origin
      >>> P = ParamSpec("P")
      >>> get_origin(P.args) is P
      True
      >>> get_origin(P.kwargs) is P
      True

  Added in version 3.10.

class typing.TypeAliasType(name, value, *, type_params=())

  通过 `type` 语句创建的类型别名的类型。

  舉例來說：

      >>> type Alias = int
      >>> type(Alias)
      <class 'typing.TypeAliasType'>

  Added in version 3.12.

  __name__

    类型别名的名称：

        >>> type Alias = int
        >>> Alias.__name__
        'Alias'

  __module__

    类型别名定义所在的模块名称:

        >>> type Alias = int
        >>> Alias.__module__
        '__main__'

  __type_params__

    类型别名的类型形参，或者如果别名不属于泛型则为一个空元组:

        >>> type ListOrSet[T] = list[T] | set[T]
        >>> ListOrSet.__type_params__
        (T,)
        >>> type NotGeneric = int
        >>> NotGeneric.__type_params__
        ()

  __value__

    类型别名的值。 它将被 惰性求值，因此别名定义中使用的名称将直到 `__value__` 属性被访问时才会被解析:

        >>> type Mutually = Recursive
        >>> type Recursive = Mutually
        >>> Mutually
        Mutually
        >>> Recursive
        Recursive
        >>> Mutually.__value__
        Recursive
        >>> Recursive.__value__
        Mutually

#### 其他特殊指令

这些函数和类不应被直接用作标注。 它们的设计目标是作为创建和声明类型的构件。

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}>'

  `NamedTuple` 子类也可以为泛型：

      class Group[T](NamedTuple):
          key: T
          group: list[T]

  反向兼容用法：

      # For creating a generic NamedTuple on Python 3.11 or lower
      class Group(NamedTuple, Generic[T]):
          key: T
          group: list[T]

      # A functional syntax is also supported
      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__` 属性。

  在 3.11 版的變更: 添加对泛型命名元组的支持。

class typing.NewType(name, tp)

  用于创建低开销的 独有类型 的辅助类。

  `NewType` 将被类型检查器视为一个独有类型。 但是，在运行时，调用 `NewType` 将原样返回其参数。

  用法：

      UserId = NewType('UserId', int)  # Declare the NewType "UserId"
      first_user = UserId(1)  # "UserId" returns the argument unchanged at runtime

  __module__

    新类型定义所在的模块。

  __name__

    新类型的名称。

  __supertype__

    新类型所基于的类型。

  Added in version 3.5.2.

  在 3.10 版的變更: `NewType` 现在是一个类而不是函数。

class typing.Protocol(Generic)

  协议类的基类。

  协议类是这样定义的:

      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 了解详情。 使用 `runtime_checkable()` 装饰的协议类（稍后将介绍）可作为只检查给定属性是否存在，而忽略其类型签名的简单的运行时协议。

  Protocol 类可以是泛型，例如：

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

  在需要兼容 Python 3.11 或更早版本的代码中，可以这样编写泛型协议:

      T = TypeVar("T")

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

  Added in version 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
      class Named(Protocol):
          name: str

      import threading
      assert isinstance(threading.Thread(name='Bob'), Named)

  備註

  `runtime_checkable()` 将只检查所需方法或属性是否存在，而不检查它们的类型签名或类型。 例如，`ssl.SSLObject` 是一个类，因此它通过了针对 Callable 的 `issubclass()` 检查。 但是，`ssl.SSLObject.__init__` 方法的存在只是引发 `TypeError` 并附带更具信息量的消息，因此它无法调用 (实例化) `ssl.SSLObject`。

  備註

  针对运行时可检查协议的 `isinstance()` 检查相比针对非协议类的 `isinstance()` 检查可能会惊人的缓慢。 请考虑在性能敏感的代码中使用替代性写法如 `hasattr()` 调用进行结构检查。

  Added in version 3.8.

  在 3.12 版的變更: 现在 `isinstance()` 的内部实现对于运行时可检查协议的检查会使用 `inspect.getattr_static()` 来查找属性 (在之前版本中，会使用 `hasattr()`)。 因此，在 Python 3.12+ 上一些以前被认为是运行时可检查协议的实例的对象可能不再被认为是该协议的实例，反之亦反。 大多数用户不太可能受到这一变化的影响。

  在 3.12 版的變更: 一旦类被创建则运行时可检查协议的成员就会被视为在运行时“已冻结”。 在运行时可检查协议上打上猴子补丁属性仍然有效，但不会影响将对象与协议进行比较的 `isinstance()` 检查。 请参阅 "Python 3.12 有什么新变化 了解更多细节。

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')

  为了在不支持 PEP 526 的旧版 Python 中使用此特性，`TypedDict` 支持两种额外的等价语法形式:

  - 使用字面量 `dict` 作为第二个参数：

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

  - 使用关键字参数：

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

  自從版本 3.11 後不推薦使用，將會自版本 3.13 中移除。: 使用关键字的语法在 3.11 中被弃用，并且会于 3.13 被移除。同时，该语法可能不被静态类型检查器支持。

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

      # 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` 中。 可以使用 `NotRequired` 将单独的键标记为非必要的:

      class Point2D(TypedDict):
          x: int
          y: int
          label: NotRequired[str]

      # Alternative syntax
      Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': NotRequired[str]})

  这意味着一个 `Point2D` `TypedDict` 可以省略 `label` 键。

  也可以通过全部指定 `False` 将所有键都标记为默认非必要的:

      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` 是默认的，它使类主体中定义的所有项目都是必需的。

  一个 `total=False` `TypedDict` 中单独的键可以使用 `Required` 标记为必要的:

      class Point2D(TypedDict, total=False):
          x: Required[int]
          y: Required[int]
          label: str

      # Alternative syntax
      Point2D = TypedDict('Point2D', {
          'x': Required[int],
          'y': Required[int],
          'label': str
      }, total=False)

  一个 `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

  `TypedDict` 也可以为泛型的：

      class Group[T](TypedDict):
          key: T
          group: list[T]

  要创建与 Python 3.11 或更低版本兼容的泛型 `TypedDict`，请显式地从 `Generic` 继承：

      T = TypeVar("T")

      class Group(TypedDict, Generic[T]):
          key: T
          group: list[T]

  `TypedDict` 可以通过注解字典（参见 註釋 (annotation) 最佳實踐 了解更多关于注解的最佳实践）、 `__total__` 、 `__required_keys__` 和 `__optional_keys__` 进行内省。

  __total__

    `Point2D.__total__` 给出了 `total` 参数的值。 例如：

        >>> 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

    该属性 只是 反映传给当前 `TypedDict` 类的``total`` 参数的值，而不反映这个类在语义上是否完整。 例如，一个 `__total__` 被设为 True 的 `TypedDict` 可能有用 `NotRequired` 标记的键，或者它可能继承自另一个设置了 `total=False` 的 `TypedDict`。 因此，使用 `__required_keys__` 和 `__optional_keys__` 进行内省通常会更好。

  __required_keys__

    Added in version 3.9.

  __optional_keys__

    `Point2D.__required_keys__` 和 `Point2D.__optional_keys__` 返回分别包含必要的和非必要的键的 `frozenset` 对象。

    标记为 `Required` 的键总是会出现在 `__required_keys__` 中而标记为 `NotRequired` 的键总是会出现在 `__optional_keys__` 中。

    为了向下兼容 Python 3.10 及更老的版本，还可以使用继承机制在同一个 `TypedDict` 中同时声明必要和非必要的键。 这是通过声明一个具有 `total` 参数值的 `TypedDict` 然后在另一个 `TypedDict` 中继承它并使用不同的 `total` 值来实现的：

        >>> 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

    Added in version 3.9.

    備註

    如果使用了 `from __future__ import annotations` 或者如果以字符串形式给出标注，那么标注不会在定义 `TypedDict` 时被求值。 因此，`__required_keys__` 和 `__optional_keys__` 所依赖的运行时内省可能无法正常工作，这些属性的值也可能不正确。

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

  Added in version 3.8.

  在 3.11 版的變更: 增加了对将单独的键标记为 `Required` 或 `NotRequired` 的支持。 参见 PEP 655。

  在 3.11 版的變更: 添加对泛型 `TypedDict` 的支持。

### 協定

下列协议由 typing 模块提供并已全被装饰为 `可在运行时检查的`。

class typing.SupportsAbs

  一个抽象基类，含一个抽象方法 `__abs__`，该方法与其返回类型协变。

class typing.SupportsBytes

  一個有抽象方法 `__bytes__` 的 ABC。

class typing.SupportsComplex

  一個有抽象方法 `__complex__` 的 ABC。

class typing.SupportsFloat

  一個有抽象方法 `__float__` 的 ABC。

class typing.SupportsIndex

  一個有抽象方法 `__index__` 的 ABC。

  Added in version 3.8.

class typing.SupportsInt

  一個有抽象方法 `__int__` 的 ABC。

class typing.SupportsRound

  一个抽象基类，含一个抽象方法 `__round__`，该方法与其返回类型协变。

### 与 IO 相关的抽象基类

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

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

### 函式與裝飾器

typing.cast(typ, val)

  把一个值转换为指定的类型。

  这会把值原样返回。对类型检查器而言这代表了返回值具有指定的类型，在运行时我们故意没有设计任何检查（我们希望让这尽量快）。

typing.assert_type(val, typ, /)

  让静态类型检查器确认 val 具有推断为 typ 的类型。

  在运行时这将不做任何事：它会原样返回第一个参数而没有任何检查或附带影响，无论参数的实际类型是什么。

  当静态类型检查器遇到对 `assert_type()` 的调用时，如果该值不是指定的类型则会报错:

      def greet(name: str) -> None:
          assert_type(name, str)  # OK, inferred type of `name` is `str`
          assert_type(name, int)  # type checker error

  此函数适用于确保类型检查器对脚本的理解符合开发者的意图:

      def complex_function(arg: object):
          # Do some complex type-narrowing logic,
          # after which we hope the inferred type will be `int`
          ...
          # Test whether the type checker correctly understands our function
          assert_type(arg, int)

  Added in version 3.11.

typing.assert_never(arg, /)

  让静态类型检查器确认一行代码是不可达的。

  舉例來說：

      def int_or_str(arg: int | str) -> None:
          match arg:
              case int():
                  print("It's an int")
              case str():
                  print("It's a str")
              case _ as unreachable:
                  assert_never(unreachable)

  在这里，标注允许类型检查器推断最后一种情况永远不会执行，因为 `arg` 要么是 `int` 要么是 `str`，而这两种选项都已被之前的情况覆盖了。

  如果类型检查器发现对 `assert_never()` 的调用是可达的，它将报告一个错误。 举例来说，如果 `arg` 的类型标注改为 `int | str | float`，则类型检查器将报告一个错误指出 `unreachable` 为 `float` 类型。 对于通过类型检查的 `assert_never` 调用，参数传入的推断类型必须为兜底类型 `Never`，而不能为任何其他类型。

  在运行时，如果调用此函数将抛出一个异常。

  也參考

  Unreachable Code and Exhaustiveness Checking 有更多关于使用静态类型进行穷尽性检查的信息。

  Added in version 3.11.

typing.reveal_type(obj, /)

  让静态类型检查器显示推测的表达式类型。

  当静态类型检查器遇到一个对此函数的调用时，它将发出带有所推测参数类型的诊断信息。 例如:

      x: int = 1
      reveal_type(x)  # Revealed type is "builtins.int"

  这在你想要调试你的类型检查器如何处理一段特定代码时很有用处。

  在运行时，此函数会将其参数类型打印到 `sys.stderr` 并不加修改地返回该参数 (以允许该调用在表达式中使用):

      x = reveal_type(1)  # prints "Runtime type is int"
      print(x)  # prints "1"

  请注意在运行时类型可能不同于类型静态检查器所推测的类型（明确程度可能更高也可能更低）。

  大多数类型检查器都能在任何地方支持 `reveal_type()`，即使并未从 `typing` 导入该名称。 不过，从 `typing` 导入该名称将允许你的代码在运行时不会出现运行时错误并能更清晰地传递意图。

  Added in version 3.11.

@typing.dataclass_transform(*, eq_default=True, order_default=False, kw_only_default=False, frozen_default=False, field_specifiers=(), **kwargs)

  将一个对象标记为提供类似 `dataclass` 行为的装饰器。

  `dataclass_transform` 可被用于装饰类、元类或本身为装饰器的函数。 使用 `@dataclass_transform()` 将让静态类型检查器知道被装饰的对象会执行以类似 `@dataclasses.dataclass` 的方式来转换类的运行时“魔法”。

  装饰器函数使用方式的例子：

      @dataclass_transform()
      def create_model[T](cls: type[T]) -> type[T]:
          ...
          return cls

      @create_model
      class CustomerModel:
          id: int
          name: str

  在基类上:

      @dataclass_transform()
      class ModelBase: ...

      class CustomerModel(ModelBase):
          id: int
          name: str

  在元类上:

      @dataclass_transform()
      class ModelMeta(type): ...

      class ModelBase(metaclass=ModelMeta): ...

      class CustomerModel(ModelBase):
          id: int
          name: str

  上面定义的 `CustomerModel` 类将被类型检查器视为类似于使用 `@dataclasses.dataclass` 创建的类。 例如，类型检查器将假定这些类具有接受 `id` 和 `name` 的 `__init__` 方法。

  被装饰的类、元类或函数可以接受以下布尔值参数，类型检查器将假定它们具有与 `@dataclasses.dataclass` 装饰器相同的效果: `init`, `eq`, `order`, `unsafe_hash`, `frozen`, `match_args`, `kw_only` 和 `slots`。 这些参数的值 (`True` 或 `False`) 必须可以被静态地求值。

  传给 `dataclass_transform` 装饰器的参数可以被用来定制被装饰的类、元类或函数的默认行为:

  參數:

    - eq_default (bool) -- 指明如果调用方省略了 `eq` 形参则应将其假定为 `True` 还是 `False`。 默认为 `True`。

    - order_default (bool) -- 指明如果调用方省略了 `order` 形参则应将其假定为 `True` 还是 `False`。 默认为 `False`。

    - kw_only_default (bool) -- 指明如果调用方省略了 `kw_only` 形参则应将其假定为 `True` 还是 `False`。 默认为 `False`。

    - frozen_default (bool) -- 指明如果调用方省略了 `frozen` 形参则应将其假定为 `True` 还是 `False`。 默认为 `False`。 .. versionadded:: 3.12

    - field_specifiers (tuple[Callable[..., Any], ...]) -- 指定一个受支持的类或描述字段的函数的静态列表，类似于 `dataclasses.field()`。 默认为 `()`。

    - **kwargs (Any) -- 接受任何其他关键字以便允许可能的未来扩展。

  类型检查器能识别下列字段设定器的可选形参:

  字段设定器的可识别形参
  形参名称 | 描述
  --- | ---
  `init` | 指明字段是否应当被包括在合成的 `__init__` 方法中。 如果未指明，则 `init` 默认为 `True`。
  `default` | 为字段提供默认值。
  `default_factory` | 提供一个返回字段默认值的运行时回调。 如果 `default` 或 `default_factory` 均未指定，则会假定字段没有默认值而在类被实例化时必须提供一个值。
  `factory` | 字段说明符上 `default_factory` 形参的别名。
  `kw_only` | 指明字段是否应被标记为仅限关键字的。 如为 `True`，字段将是仅限关键字的。 如为 `False`，它将不是仅限关键字的。 如未指明，则将使用以 `dataclass_transform` 装饰的对象的 `kw_only` 形参的值，或者如果该值也未指明，则将使用 `dataclass_transform` 上 `kw_only_default` 的值。
  `alias` | 提供字段的替代名称。 该替代名称会被用于合成的 `__init__` 方法。

  在运行时，该装饰器会将其参数记录到被装饰对象的 `__dataclass_transform__` 属性。 它没有其他的运行时影响。

  更多細節請見 PEP 681。

  Added in version 3.11.

@typing.overload

  用于创建重载函数和方法的装饰器。

  `@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 goes here

  请参阅 PEP 484 了解更多细节以及与其他类型语义的比较。

  在 3.11 版的變更: 现在可以使用 `get_overloads()` 在运行时内省有重载的函数。

typing.get_overloads(func)

  为 func 返回以 `@overload` 装饰的定义的序列。

  func 是用于实现过载函数的函数对象。 例如，根据文档中为 `@overload` 给出的 `process` 定义，`get_overloads(process)` 将为所定义的三个过载函数返回由三个函数对象组成的序列。 如果在不带过载的函数上调用，`get_overloads()` 将返回一个空序列。

  `get_overloads()` 可被用来在运行时内省一个过载函数。

  Added in version 3.11.

typing.clear_overloads()

  清空内部注册表中所有已注册的重载。

  这可用于回收注册表所使用的内存。

  Added in version 3.11.

@typing.final

  表示最终化方法和最终化类的装饰器。

  以 `@final` 装饰一个方法将向类型检查器指明该方法不可在子类中被重载。 以 `@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。

  Added in version 3.8.

  在 3.11 版的變更: 该装饰器现在将尝试在被装饰的对象上设置 `__final__` 属性为 `True`。 这样，可以在运行时使用 `if getattr(obj, "__final__", False)` 这样的检查来确定对象 `obj` 是否已被标记为终结。 如果被装饰的对象不支持设置属性，该装饰器将不加修改地返回对象而不会引发异常。

@typing.no_type_check

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

  此作用方式类似于类或函数的 decorator。 对于类，它将递归地应用到该类中定义的所有方法和类（但不包括在其超类或子类中定义的方法）。 类型检查器将忽略带有此装饰器的函数或类的所有标注。

  `@no_type_check` 将原地改变被装饰的对象。

@typing.no_type_check_decorator

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

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

@typing.override

  该装饰器指明子类中的某个方法是重载超类中的方法或属性。

  如果一个以 `@override` 装饰的方法实际未重载任何东西则类型检查器应当报告错误。 这有助于防止当基类发生修改而子类未进行相应修改而导致的问题。

  舉例來說：

      class Base:
          def log_status(self) -> None:
              ...

      class Sub(Base):
          @override
          def log_status(self) -> None:  # Okay: overrides Base.log_status
              ...

          @override
          def done(self) -> None:  # Error reported by type checker
              ...

  没有对此特征属性的运行时检查。

  该装饰器将尝试在被装饰的对象上设置 `__override__` 属性为 `True`。 这样，可以在运行时使用 `if getattr(obj, "__override__", False)` 这样的检查来确定对象 `obj` 是否已被标记为重载。 如果被装饰的对象不支持设置属性，该装饰器将不加修改地返回对象而不会引发异常。

  更多細節請見 PEP 698。

  Added in version 3.12.

@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` 和 (如果可用) 类型形参 命名空间中执行求值来处理的。 对于一个类 `C`，将返回一个由所有 `__annotations__` 与 `C.__mro__` 逆序合并构建而成的字典。

  本函数会递归地将所有 `Annotated[T, ...]` 替换为 `T`，除非 `include_extras` 被设为 `True` (请参阅 `Annotated` 了解详情)。 例如:

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

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

  備註

  `get_type_hints()` 在导入的 类型别名 中不工作，包括前向引用。启用注解的延迟评估（ PEP 563 ）可能会消除对大多数前向引用的需要。

  在 3.9 版的變更: 新增 `include_extras` 參數（如 PEP 593 中所述）。更多資訊請見 `Annotated` 的文件。

  在 3.11 版的變更: 在之前，如果设置了等于 `None` 的默认值则会为函数和方法标注添加 `Optional[t]`。 现在标注将被不加修改地返回。

typing.get_origin(tp)

  获取一个类型的不带下标的版本：对于 `X[Y, Z, ...]` 形式的类型对象将返回 `X`。

  如果 `X` 是一个内置类型或 `collections` 类在 typing 模块中的别名，它将被正规化为原始的类。 如果 `X` 是 `ParamSpecArgs` 或 `ParamSpecKwargs` 的实例，则返回下层的 `ParamSpec`。 对于不受支持的对象将返回 `None`。

  舉例：

      assert get_origin(str) is None
      assert get_origin(Dict[str, int]) is dict
      assert get_origin(Union[int, str]) is Union
      P = ParamSpec('P')
      assert get_origin(P.args) is P
      assert get_origin(P.kwargs) is P

  Added in version 3.8.

typing.get_args(tp)

  获取已执行所有下标的类型参数：对于 `X[Y, Z, ...]` 形式的类型对象将返回 `(Y, Z, ...)`。

  如果 `X` 是一个并集或是包含在另一个泛型类型中的 `Literal`，则 `(Y, Z, ...)` 的顺序可能因类型缓存而与原始参数 `[Y, Z, ...]` 存在差异。 对于不受支持的对象将返回 `()`。

  舉例：

      assert get_args(int) == ()
      assert get_args(Dict[int, str]) == (int, str)
      assert get_args(Union[int, str]) == (int, str)

  Added in version 3.8.

typing.is_typeddict(tp)

  检查一个类型是否为 `TypedDict`。

  舉例來說：

      class Film(TypedDict):
          title: str
          year: int

      assert is_typeddict(Film)
      assert not is_typeddict(list | str)

      # TypedDict is a factory for creating typed dicts,
      # not a typed dict itself
      assert not is_typeddict(TypedDict)

  Added in version 3.10.

class typing.ForwardRef

  用于字符串前向引用的内部类型表示的类。

  例如，`List["SomeClass"]` 会被隐式转换为 `List[ForwardRef("SomeClass")]`。 `ForwardRef` 不应由用户来实例化，但可以由内省工具使用。

  備註

  PEP 585 泛型类型例如 `list["SomeClass"]` 将不会被隐式地转换为 `list[ForwardRef("SomeClass")]` 因而将不会自动解析为 `list[SomeClass]`。

  Added in version 3.7.4.

### 常數

typing.TYPE_CHECKING

  会被第 3 方静态类型检查器假定为 `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`，函数定义时则不求值注解，直接把注解以字符串形式存在 `__annotations__` 里。这时毋需为注解打引号（见 PEP 563）。

  Added in version 3.5.2.

### 棄用的別名

本模块给标准库中已有的类定义了许多别名，这些别名现已不再建议使用。起初 typing 模块包含这些别名是为了支持用 `[]` 来参数化泛型类。然而，在 Python 3.9 中，对应的已有的类也支持了 `[]` (参见 PEP 585)，因此这些别名了就成了多余的了。

这些多余的类型从 Python 3.9 起被弃用。然而，虽然它们可能会在某一时刻被移除，但目前还没有移除它们的计划。因此，解释器目前不会对这些别名发出弃用警告。

一旦确定了何时这些别名将被移除，解释器将比正式移除之时提前至少两个版本发出弃用警告 (deprecation warning)。但保证至少在 Python 3.14 之前，这些别名仍会留在 typing 模块中，并且不会引发弃用警告。

如果被类型检查器检查的程序旨在运行于 Python 3.9 或更高版本，则鼓励类型检查器标记出这些不建议使用的类型。

#### 內建型別的別名

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

  棄用 `dict` 的別名。

  请注意，要注解参数，更推荐使用 `Mapping` 这样的抽象容器类型，而不是使用 `dict` 或者 `typing.Dict` 。

  该类型用法如下：

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

  在 3.9 版之後被棄用: `builtins.dict` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

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

  棄用 `list` 的別名。

  请注意，要注解参数，更推荐使用 `Sequence` 或者 `Iterable` 这样的抽象容器类型，而不是使用 `list` 或者 `typing.List` 。

  该类型用法如下：

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

      def keep_positives[T: (int, float)](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` 这样的抽象容器类型，而不是使用 `set` 或者 `typing.Set` 。

  在 3.9 版之後被棄用: `builtins.set` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

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

  棄用 `builtins.frozenset` 的別名。

  在 3.9 版之後被棄用: `builtins.frozenset` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

typing.Tuple

  棄用 `tuple` 的別名。

  `tuple` 和 `Tuple` 是类型系统中的特例；更多详细信息请参见 註釋元組 (tuple)。

  在 3.9 版之後被棄用: `builtins.tuple` 现在支持下标操作（`[]`）。参见 PEP 585 和 GenericAlias 类型。

class typing.Type(Generic[CT_co])

  棄用 `type` 的別名。

  有关在类型注解中使用 `type` 或 `typing.Type` 的详细信息，请参阅 類別物件的型別 。

  Added in version 3.5.2.

  在 3.9 版之後被棄用: `builtins.type` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

#### `collections` 中型別的別名

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

  棄用 `collections.defaultdict` 的別名。

  Added in version 3.5.2.

  在 3.9 版之後被棄用: `collections.defaultdict` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

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

  棄用 `collections.OrderedDict` 的別名。

  Added in version 3.7.2.

  在 3.9 版之後被棄用: `collections.OrderedDict` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

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

  棄用 `collections.ChainMap` 的別名。

  Added in version 3.6.1.

  在 3.9 版之後被棄用: `collections.ChainMap` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

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

  棄用 `collections.Counter` 的別名。

  Added in version 3.6.1.

  在 3.9 版之後被棄用: `collections.Counter` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

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

  棄用 `collections.deque` 的別名。

  Added in version 3.6.1.

  在 3.9 版之後被棄用: `collections.deque` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

#### 其他具体类型的别名

> 自從版本 3.8 後不推薦使用，將會自版本 3.13 中移除。: `typing.io` 命名空间被弃用并将被删除。 这些类型应该被直接从 `typing` 导入。

class typing.Pattern
class typing.Match

  `re.compile()` 和 `re.match()` 的返回类型的已弃用的别名。

  这些类型（与对应的函数）是 `AnyStr` 上的泛型。 `Pattern` 可以被特化为 `Pattern[str]` 或 `Pattern[bytes]`；`Match` 可以被特化为 `Match[str]` 或 `Match[bytes]`。

  自從版本 3.8 後不推薦使用，將會自版本 3.13 中移除。: `typing.re` 命名空间被弃用并将被删除。 这些类型应该被直接从 `typing` 导入。

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

class typing.Text

  棄用 `str` 的別名。

  `Text` 被用来为 Python 2 代码提供向上兼容的路径：在 Python 2 中，`Text` 是 `unicode` 的别名。

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

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

  Added in version 3.5.2.

  在 3.11 版之後被棄用: Python 2 已不再受支持，并且大部分类型检查器也都不再支持 Python 2 代码的类型检查。 目前还没有计划移除该别名，但建议用户使用 `str` 来代替 `Text`。

#### `collections.abc` 中容器 ABC 的別名

class typing.AbstractSet(Collection[T_co])

  棄用 `collections.abc.Set` 的別名。

  在 3.9 版之後被棄用: `collections.abc.Set` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

class typing.ByteString(Sequence[int])

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

  自從版本 3.9 後不推薦使用，將會自版本 3.14 中移除。: 首选 `collections.abc.Buffer`，或是 `bytes | bytearray | memoryview` 这样的并集。

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

  棄用 `collections.abc.Collection` 的別名。

  Added in version 3.6.

  在 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, AbstractSet[tuple[KT_co, VT_co]])

  棄用 `collections.abc.ItemsView` 的別名。

  在 3.9 版之後被棄用: `collections.abc.ItemsView` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

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

  棄用 `collections.abc.KeysView` 的別名。

  在 3.9 版之後被棄用: `collections.abc.KeysView` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

class typing.Mapping(Collection[KT], Generic[KT, 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)

  棄用 `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, Collection[_VT_co])

  棄用 `collections.abc.ValuesView` 的別名。

  在 3.9 版之後被棄用: `collections.abc.ValuesView` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

#### `collections.abc` 中异步 ABC 的别名

class typing.Coroutine(Awaitable[ReturnType], Generic[YieldType, SendType, ReturnType])

  棄用 `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

  Added in version 3.5.3.

  在 3.9 版之後被棄用: `collections.abc.Coroutine` 现在支持下标操作（`[]`）。参见 PEP 585 和 GenericAlias 类型。

class typing.AsyncGenerator(AsyncIterator[YieldType], Generic[YieldType, SendType])

  棄用 `collections.abc.AsyncGenerator` 的別名。

  异步生成器可由泛型类型 `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)

  Added in version 3.6.1.

  在 3.9 版之後被棄用: `collections.abc.AsyncGenerator` 现在支持下标操作（`[]`）。参见 PEP 585 和 GenericAlias 类型。

class typing.AsyncIterable(Generic[T_co])

  棄用 `collections.abc.AsyncIterable` 的別名。

  Added in version 3.5.2.

  在 3.9 版之後被棄用: `collections.abc.AsyncIterable` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

class typing.AsyncIterator(AsyncIterable[T_co])

  棄用 `collections.abc.AsyncIterator` 的別名。

  Added in version 3.5.2.

  在 3.9 版之後被棄用: `collections.abc.AsyncIterator` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

class typing.Awaitable(Generic[T_co])

  棄用 `collections.abc.Awaitable` 的別名。

  Added in version 3.5.2.

  在 3.9 版之後被棄用: `collections.abc.Awaitable` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

#### `collections.abc` 中其他 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 类型。

typing.Callable

  棄用 `collections.abc.Callable` 的別名。

  有关如何在类型标注中使用 `collections.abc.Callable` 和 `typing.Callable` 的详细信息请参阅 註釋 callable 物件。

  在 3.9 版之後被棄用: `collections.abc.Callable` 现在支持下标操作（`[]`）。参见 PEP 585 和 GenericAlias 类型。

  在 3.10 版的變更: `Callable` 現已支援 `ParamSpec` 以及 `Concatenate`。請參閱 PEP 612 閱讀詳細內容。

class typing.Generator(Iterator[YieldType], Generic[YieldType, SendType, ReturnType])

  棄用 `collections.abc.Generator` 的別名。

  生成器可以由泛型类型 `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` 的別名。

  在 3.12 版之後被棄用: 改為直接使用 `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` 的別名。

  在 3.12 版之後被棄用: 改為直接使用 `collections.abc.Sized`。

#### `contextlib` ABC 的別名

class typing.ContextManager(Generic[T_co])

  `contextlib.AbstractContextManager` 的已弃用的别名。

  Added in version 3.5.4.

  在 3.9 版之後被棄用: `contextlib.AbstractContextManager` 现在支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

class typing.AsyncContextManager(Generic[T_co])

  `contextlib.AbstractAsyncContextManager` 的已弃用的别名。

  Added in version 3.6.2.

  在 3.9 版之後被棄用: `contextlib.AbstractAsyncContextManager` 现在 支持下标操作 (`[]`)。 参见 PEP 585 和 GenericAlias 类型。

## 主要特性的弃用时间线

`typing` 的某些特性被弃用，并且可能在将来的 Python 版本中被移除。下表总结了主要的弃用特性。该表可能会被更改，而且并没有列出所有的弃用特性。

特性 | 棄用於 | 计划移除 | PEP/问题
--- | --- | --- | ---
`typing.io` 和 `typing.re` 子模組 | 3.8 | 3.13 | bpo-38291
标准容器的 `typing` 版本 | 3.9 | 未定（请参阅 棄用的別名 了解详情） | PEP 585
`typing.ByteString` | 3.9 | 3.14 | gh-91896
`typing.Text` | 3.11 | 未确定 | gh-92332
`typing.Hashable` 和 `typing.Sized` | 3.12 | 未确定 | gh-94309
`typing.TypeAlias` | 3.12 | 未确定 | PEP 695