由于Python不需要在声明变量时声明变量类型,所有变量类型都是在运行时动态确定的,因此许多功能经过函数的层层封装,我们很难判断出一个函数的输入输出的具体类型。因此在python3.5以后版本支持类型注解(typing)。
一个简单函数,接受字符串,返回字符串示例def greeting(name: str) -> str:
return 'Hello ' + name
在函数greeting中,参数name是一个str类型,并返回值str类型
复杂一点,参数使用默认值def add(x: int, y: int = 2) -> int:
return x + y
在函数add中,x,y都是一个整数类型,且y默认值为2,并返回一个int类型
函数中使用list,dict类型def get_student(student_li: list) -> dict:
pass
类型别名
类型别名通过将类型分配给别名来定义。在这个例子中, Vector 和 List[float] 将被视为可互换的同义词:from typing import List
Vector = List[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
# 类型检查; 浮点数列表可作为Vector。
new_vector = scale(2.0, [1.0, -4.2, 5.4])
类型别名可用于简化复杂类型签名。例如:ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]
def broadcast_message(message: str, servers: Sequence[Server]) -> None:
...
#静态类型检查器会将先前的类型签名视为
#与此完全相同。
def broadcast_message(
message: str,
servers: Sequence[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
...
请注意,None 作为类型提示是一种特殊情况,并且由 type(None) 取代。
NewType
使用 NewType() 辅助函数创建不同的类型:from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
静态类型检查器会将新类型视为它是原始类型的子类。这对于帮助捕捉逻辑错误非常有用:def get_user_name(user_id: UserId) -> str:
...
# 静态类型检查器
user_a = get_user_name(UserId(42351))
# 不进行类型检查; 一个int不是一个UserId
user_b = get_user_name(-1)
您仍然可以对 UserId 类型的变量执行所有的 int 支持的操作,但结果将始终为 int 类型。这可以让你在需要 int 的地方传入 UserId,但会阻止你以无效的方式无意中创建 UserId:# “输出”的类型为“ int”,而不是“ UserId”
output = UserId(23413) + UserId(54341)
更多相关类型检查,请参考: