python是一门解释型、动态类型语言。所谓的解释型指:语法在执行时运行而无需提前编译。所谓动态类型指:变量的类型无需创建时显式声明,解释器会在运行时指向可能的类型。这些特点使得python灵活、弹性,但也会导致代码阅读的不便,进而导致代码维护的困难。因此从3.5版本开始,python引入了typing模块提供类型提示功能(注意:仅仅是提示,即使传入值与规定不符,也不会报错!),而pycharm的IDE也能够据此进行类型检测和自动补全提示。
使用typing模块来书写函数的基本格式如下:
from typing import List
from functools import reduce
def func(x:str, y: List)->str:
return x + ' ' + reduce(lambda a, b: str(a)+str(b), y)
if __name__ == '__main__':
print(func('hello', ['w', 'o', 'r', 'l', 'd'])) # hello world
参数后面接:type
指定类型提示,)
后接->type
指定返回值类型提示。定义完成后,可通过对象的__annotations__
属性查看所有定义的类型声明。
常见的类型标注包括:
1. 基础变量类型
包括字符型str
,字节型bytes
,整数型int
,浮点型float
,布尔型bool
,空类型None
等,直接指定即可,无需使用typing模块。
def func(x:str, y:int)->str:
return x + str(y)
2. 容器类型
比如列表List
,元组Tuple
, 字典类型Dict
,集合类型Set
,映射类型Map
, 序列类型Sequence
等
from typing import Mapping, Sequence, Tuple
# 1. 例子1:
def mapper(a: str, b: int, c: str, d: float)-> Tuple[float, str]:
return b+d, a+c
# 2. 例子2:
def cat(babies: Sequence[str], attrs: Mapping[str, str])-> None:
print("It has babies: {} and has attrs: {}".format(','.join(babies), attrs))
3. 可迭代类型
包括可迭代对象类型Iterable
、迭代器类型Iterator
和生成器类型Generator
.
4. 可执行型
指Callable
,即实现了__call__
方法的对象,注意Callable
本省需要同时指定输入和输出的对象类型,且输入和输出之间、各输入参数之间均通过中括号分隔。
from typing import Callable, List
from functools import reduce
def func(x:str, y: List)->str:
return x + ' ' + reduce(lambda a, b: str(a)+str(b), y)
def func2(f:Callable[[str, List], str], x:str, y: List)-> None:
print(f(x, y))
if __name__ == '__main__':
func2(func, 'hello', ['w', 'o', 'r', 'l', 'd'])
5. 泛型
所谓泛型类型,指可以让一个类或方法支持多种数据类型,从而提高代码的可复用性,和灵活性。
在typing库中涉及泛型定义的包括Generic
,TypeVar
,Union
、Opiton
等。其中Opition(type1)
的效果等同于Union(type1, None)
,而Union
from typing import Union, TypeVar
# 例子1
A = TypeVar('A', str, bytes) # str或bytes, 通过定义统一的TypeVar可以方便操作
def longest(x: A, y: A) -> A:
'''Return the longest of two strings.'''
return x if len(x) >= len(y) else y
# 例子2
def pprint(x: Union[str, bytes])-> None: # str或bytes
print(x)