Type Hint With TypeVar and Generic

Keywords: Python, typing, type hint, type hints, typehint, typehints, typevar, generic

TypeVarGeneric 是类型提示中非常重要的两个函数, 都是为了泛型而服务的. TypeVar 用于定义泛型变量, Generic 用于定义泛型类.

我们先来看 TypeVar 的基础用法.

 1# -*- coding: utf-8 -*-
 2
 3"""
 4我们有一个函数, 它的输入参数的类型和输出参数的类型是发生联动的, 但是这个具体的类型是不确定的.
 5举例来说, 如何用 Typehint 标注输入的参数是 A 类型, 输出的参数也是 A 类型呢?
 6我们来看下面这个例子. 我们实现了一个类似于 dict.get() 的方法, 不过输入的 dict 可以是任何
 7mapper, key 和 value 都可以是任何类型.
 8"""
 9
10import typing as T
11
12# 标注一个 key 和 value 的类型
13KT = T.TypeVar("KT") # key type
14VT = T.TypeVar("VT") # value type
15
16def get_value_by_key(
17    # 入参中定义 mapping 的 key 是 KT, value 是 VT
18    mapping: T.Mapping[KT, VT],
19    # 获得的 key 是 KT
20    key: KT,
21    # 默认值是 VT
22    default: VT
23) -> VT: # 返回值是 VT
24    try:
25        return mapping[key]
26    except KeyError:
27        return default
28
29# 如果 Type 正确, 那么 IDE 可以提示以下方法
30# int.bit_count()
31# str.split()
32
33# Type 正确
34v = get_value_by_key(mapping={"a": 1, "b": 2}, key="a", default=0)
35# 可以提示 bit_count 方法
36v.bit_count()
37
38# Type 正确
39v = get_value_by_key(mapping={1: "a", 2: "b"}, key=1, default="c")
40# 可以提示 split 方法
41v.split()
42
43# Type 不正确, IDE 提示 default="c" 不对
44v = get_value_by_key(mapping={"a": 1, "b": 2}, key="a", default="c")