python参数类型注解
-
Python是动态语言,变量随时可以被赋值,且能赋值为不同的类型
-
Python不是静态编译型语言,变量类型是在运行期决定的
-
动态语言很灵活,但是这种特性也是弊端
def add(x, y):
return x + y
print(add(4, 5))
print(add('hello', 'world'))
add(4, 'hello') #int与数字类型不能相加,报错
-
难发现:由于不做任何类型检查,直到运行期问题才显现出来,或者线上运行时才能暴露出问 题
-
难使用:函数的使用者看到函数的时候,并不知道你的函数的设计,并不知道应该传入什么类 型的数据
-
如何解决这种动态语言定义的弊端呢?
- 增加文档Documentation String
- 这只是一个惯例,不是强制标准,不能要求程序员一定为函数提供说明文档
- 函数定义更新了,文档未必同步更新
- 增加文档Documentation String
def add(x:int,y:int):#注解只是注释性作用,不具有执行功能
"""
x:int
y:int
return:int
""" # 也可以使用三个引号进行文档字符串形式标注,但是文档更新不及时
return x+y
-
函数注解
- Python 3.5引入
-
对函数的参数进行类型注解
- 对函数的返回值进行类型注解
- 只对函数参数做一个辅助的说明,并不对函数参数进行类型检查
- 提供给第三方工具,做代码分析,发现隐藏的bug
- 函数注解的信息,保存在 annotations 属性中
变量注解
- Python 3.6引入。注意它也只是一种对变量的说明,非强制 i : int = 3
业务应用
-
函数参数类型检查
-
思路
- 函数参数的检查,一定是在函数外,如要把检查代码侵入到函数中
- 函数应该作为参数,传入到检查函数中
- 检查函数拿到函数传入的实际参数,与形参声明对比
- **__annotations__**属性是一个字典,其中包括返回值类型的声明。假设要做位置参数的判断,无 法和字典中的声明对应。使用i
nspect
模块
-
inspet
模块- 提供获取对象信息的函数,可以检查函数和类、类型检查
inspect 模块
- signature(callable),获取签名(函数签名包含了一个函数的信息,包括函数名、它的参数类型、它所在的类和名称空间及其他信息)
import inspect
inspect.isfunction(int)
inspect.signature(add)# 得到函数的签名与函数的注解,包括return值
def add(x:int,y:int,*args,**kwargs)-->int:
return x+y
sig = inspect.signature(add)# 得到函数的签名与函数的注解,包括return值
print(sig,type(sig))
>>>(x:int, y:int, *args, **kwargs) -> int <class 'inspect.Signature'>
# sig 的类型为 <class 'inspect.Signature'>
sig.parameters
>>>mappingproxy({
'x': <Parameter "x:int">,
'y': <Parameter "y:int">,
'args':