python-typing&type hint

python是动态语言,不用为参数和变量声明类型,但是可以用泛型来描述参数变量的类型来提高代码的可读性(泛型或泛型变量或实际类型都可以用来描述这个参数或变量的类型)

# 不使用类型提示

def func(a,b):
  return a+b

func('1','1') # '11'
func(1,1)     # 2
func('1',1)   # 未使用类型提示,代码编辑时不会报错,代码执行时会报错

# 使用类型提示
from typing import overload

@overload
def func(a: int, b: int): pass

@overload
def func(a: str, b: str): pass

def func(a, b):
    return a + b

func(1, '1')  # 使用类型提示,在代码编辑时就会报错,可以在代码执行前预防可能出现的问题

type hint

提示类型并不是可用类型,如typing.List并不是list的子类,typing.List只是一个type hint,对a参数指定一个type hint,这个type hint会被设置为func方法a入参的type hint属性,执行代码不会其任何作用,但是执行代码过程中可以获取到这个type hint属性,并使用它做一些处理

常见type hint

  • List是list的泛型(泛型:表示某种类型)
  • Tuple是tuple的泛型
  • NamedTuple是collections.namedtupe的泛型
  • Dict是dict的泛型
  • Mapping是collections.Mapping的泛型
  • Set是set的泛型
  • Sequence是collection.Sequence的泛型/tuple+list的泛型
  • NoReturn是无返回的泛型
  • Any是任意类型的泛型
  • TypeVar,可以创建泛型变量,就是传什么泛型就是什么泛型(T = TypeVar('T'))
  • NewType,一个新的类型(不是泛型),List=NewType('List', list)``Person=NewType('Person', str)
  • Callable是可调用类型的泛型
  • Union是联合类型
  • Optional是可为空的联合类型
  • Generator是一个生成器类型

typing.Generic&typing.TypeVar

from typing import Generic, TypeVar, List
T = TypeVar('T')  # 定义一个泛型变量, 接收什么泛型这个泛型变量就是什么泛型

class Base(Generic[T]):    # 定义一个Base,Base会用到一个泛型T
  def set_t(self, t: T):
    self.t = T
  def get_t(self) -> T:
    return self.t

class BaseList(Base[List]):# 继承Base类型并进一步定义T,让T=List, Base[List]就和Dict[str, Any]一样的道理,都是List/str/any描述Base或List类内部参数类型
  pass

base_list = BaseList()
base_list.set_t(t='') # 这里入参t需要传T=>List类型,这里传str,idea竟然没有检查到类型
base_list.get_t().append()     # 这里get_t返回的是T=>List类型,idea会提示List的方法

目前idea对部分type hint不支持,但是使用type hint代码的可读性更高
每个类型都有自己的泛型,如List,Tuple,实际类型list/tuple等也可以做类型提示
Union/Optional定义可选泛型, Union[int,str], 描述参数可以选择传int,也可以选择传str
TypeVar定义一个可变的泛型变量,泛型变量可以接收泛型/实际类型,T=TypeVar('T', bound=xxx)
Generic定义一组泛型,Base(Generic[T]) -> BaseChild(Base[List])

原文地址:https://www.cnblogs.com/bonus_scene/p/15187506.html