Python标准库typing
简介
-
python3.5+才有
-
Python 运行时不强制执行函数和变量类型注解,但这些注解可用于类型检查器、IDE、静态检查器等第三方工具。
-
作用
- 类型检查,防止运行时出现参数和返回值类型不符合。(pycharm会自动联想类型)
- 作为开发文档附加说明,方便使用者调用时传入和返回参数类型。
- 该模块加入后并不会影响程序的运行,不会报正式的错误,只有提醒
-
最早接触是在leetcode做题的时候看到的,后面在各种源码中广泛有看到。
-
比如LeetCode算法第一题:两数之和,的解题模板(python3)
class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]:
-
比如Selenium中get方法的源码
def get(self, url: str) -> None: """ Loads a web page in the current browser session. """ self.execute(Command.GET, {'url': url})
-
实例
变量定义
-
示例代码
name:str name = 'wuxianfeng' print(name.upper())
-
PEP8中有提及,在声明变量类型时,变量后方紧跟一个冒号,冒号后面跟一个空格,再跟上变量的类型。
-
其实我们很少这么做就是了。更多是放在函数或者方法中
函数参数(基础类型)
-
示例代码
def greeting(name: str) -> str: return 'Hello ' + name
- 声明name参数是str类型,格式是参数名冒号类型
- 返回对象也是str类型,格式是->类型,注意是一个-
- ->先写,再写冒号!
-
语法
参数名:类型 def 函数名(参数...) -> 类型:
-
一个好处就是用pycharm在输入代码的时候
def func(name:str) ->None: print(name.) #输入到name.的时候能自动补齐出来str类型的方法,如果不声明绝对是没有的
-
str是默认类型,你发现跟typing模块好像并没任何关系,因为这是基础的模块,无需导入即可使用。类似的还有int,float,bool等
函数参数默认值
-
示例代码:Faker类的初始化方法
def __init__( self, locale: Optional[Union[str, Sequence[str], Dict[str, Union[int, float]]]] = None, providers: Optional[List[str]] = None, generator: Optional[Generator] = None, includes: Optional[List[str]] = None, use_weighting: bool = True, **config: Any, ) -> None:
-
语法
参数名:类型=默认值 实例: use_weighting: bool = True
-
跟以前相比就是加了冒号和类型
高级类型List和Tuple
-
此处的中级类型指的是List和Tuple,Dict这些
-
示例代码:文章开头提到的leetcode第一题,两数之和
class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]:
- 意思是nums这个参数是一个list,其中每个元素是int类型的
-
注意,代码模板不会显示所有的细节,其实这是需要导入的
from typing import Dict, List, Tuple
-
实例代码1
from typing import List def func(names:List[str]) -> None: for name in names: #如果你输入names.,会产生列表的方法 print(name) #如果你输入name.,会产生字符串的方法 names = ['wuxianfeng','qianyuli'] func(names)
-
注意上述代码跟以下代码的区别
def func1(*names): for name in names: print(name) classes = ['c1','c2'] func1(*classes)
-
-
实例代码2:多个相同类型可以用...来替代,但要注意是Tuple[]
from typing import Tuple def func(ages: Tuple[int, ...]) -> None: for age in ages: print(age) ages = (18, 19, 22, 34,) func(ages)
-
此处比较诡异的是如果我写
from typing import Tuple def func(ages: Tuple[int,int]) -> None: for age in ages: print(age) ages = (18, 19, 22, 34,) #这里只能写2个值,多或者少都会警告! func(ages) #应为类型Tuple[int,int],实为类型Tuple[int,int,int,int]
-
但是List却没有这个问题,后续有空查下
-
高级类型Dict
-
dict是key:value形式
-
注意跟Tuple一样,都是[]的形式,不能是{}
-
实例代码
from typing import Dict def func(info: Dict[str, str]) -> None: for k, v in info.items(): print(k) print(v) nanjings = {'wuxianfeng': 'male', 'qianyuli': 'female'} func(nanjings)
类型别名
-
示例
from typing import List Alias = List[int] #这里可以是List或者list def scale(orgin_num: int, vector: Alias) -> Alias: return [orgin_num * vec for vec in vector] print(scale(2, [3,4,5]))
类型嵌套
-
示例
from typing import List def func(vars: List[List[int]]) -> None: for _ in vars: for __ in _: print(__) func([[1, 2], [2, 3]])
可选类型Optional
-
示例代码
from typing import Optional def func(arg: Optional[int] = None): print(arg) func() func(1)
-
显然你去掉=None是不行的,func()的时候会提示错误
-
Optional[int] 等价于 Union[int, None]
小结
-
str、int、float、bool无需声明,直接用即可
-
List是list的泛型,其后紧跟一个方括号,里面代表了构成这个列表的元素类型。
age:List[int] var: List[int or float] = [2, 3.5] vars: List[List[int]] = [[1, 2], [2, 3]]
-
Tuple、元组,是 tuple 的泛型,其后紧跟一个方括号,方括号中按照顺序声明了构成本元组的元素类型
Tuple[X, Y] 代表了构成元组的第一个元素是 X 类型,第二个元素是 Y 类型 person: Tuple[str, int, float] = ('Mike', 22, 1.75)
- NamedTuple,是 collections.namedtuple 的泛型,实际上就和 namedtuple 用法完全一致
-
Dict、字典,是 dict 的泛型;Mapping,映射,是 collections.abc.Mapping 的泛型。根据官方文档,Dict 推荐用于注解返回类型,Mapping 推荐用于注解参数。它们的使用方法都是一样的,其后跟一个中括号,中括号内分别声明键名、键值的类型
def size(rect: Mapping[str, int]) -> Dict[str, int]: return {'width': rect['width'] + 100, 'height': rect['width'] + 100}
- MutableMapping 则是 Mapping 对象的子类,在很多库中也经常用 MutableMapping 来代替 Mapping
-
Set、集合,是 set 的泛型;AbstractSet、是 collections.abc.Set 的泛型。根据官方文档,Set 推荐用于注解返回类型,AbstractSet 用于注解参数。它们的使用方法都是一样的,其后跟一个中括号,里面声明集合中元素的类型
def describe(s: AbstractSet[int]) -> Set[int]: return set(s)