python 类型注解
函数定义的弊端
- python 是动态语言,变量随时可以被赋值,且能赋值为不同类型
- python 不是静态编译型语言,变量类型是在运行器决定的
- 动态语言很灵活,但是这种特性也是弊端
def add(x,y):
return x+y
print(add(4,5))
print(add('hello','world'))
print(add(4,'hello')) #报错,TypeError: unsupported operand type(s) for +: 'int' and 'str'
- 难发现:由于不做任何类型检查,直到运行期问题才显现出来,或者线上运行时才能暴露出问题
- 难使用:函数的使用者看到函数的时候,并不知道你的函数的设计,并不知道应该传入什么类型数据
如何解决这种动态语言定义的弊端呢?
- 增加文档Docmentation String
- 这是一个惯例,不是强制标准,不能要求程序员一定为函数提供说明文档
- 函数定义更新了,文档未必同步更新
def add(x,y):
"""
:param x:int
:param y:int
:return:int
"""
return x+y
print(help(add))
- 函数注解
- python3.5引入
- 对函数的参数进行类型注解
- 对函数的返回值进行类型注解
- 只对函数参数做一个辅助说明,并不对函数参数进行类型检查
- 提供给第三方工具,做代码分析,发现隐形bug
- 函数注解的信息,保存在__annotations__属性中
- python3.6中引入变量注解
- i:int = 3
def add(x:int,y:int)->int:
"""
:param x:int
:param y:int
:return:int
"""
return x+y
print(help(add))
print(add(4,5))
print(add("jax","zhai")) #在pycharm里参数是灰色
函数参数类型检查
思路:
- 函数参数的检查,一定是在函数外
- 函数应该作为参数,传入到检查函数中
- 检查函数拿到函数传入的实际参数,与形参声明对比
- __annotations__属性是一个字典,其中包括返回值类型的声明,假设要做一个位置参数的判断,无法和字典中的声明对应,使用inspect模块
- inspect模块
- 提供获取对象信息的函数,可以检查函数和类、类型检查
inspect模块
- signature(callable),获取签名(函数签名包含一个函数的信息,包括函数名、它的参数类型、它所在的类和名称空间及其他信息)
import inspect
def add(x:int,y:int,*args,**kwargs)->int:
return x+y
sig = inspect.signature(add)
print(sig,type(sig)) #获取签名
print('params :',sig.parameters) #OrderedDict
print('return :',sig.return_annotation) #返回值类型
print(sig.parameters['y'], type(sig.parameters['y']))
print(sig.parameters['x'].annotation)
print(sig.parameters['args'])
print(sig.parameters['args'].annotation)
print(sig.parameters['kwargs'])
print(sig.parameters['kwargs'].annotation)
inspect.isfunction(add) #是不是函数
inspect.ismethod(add) #是不是类方法
inspect.isgenerator(add) #是不是生成器
inspect.isclass(add) #是不是类
inspect.ismodule(add) #是不是模块
inspect.isbuiltin(add) #是不是内建对象
- Parameter对象
- 保存在元组中,是只读的
- name ,参数的名字
- annotation 参数注解,可能没有定义
- default 参数的缺省值,可能没有定义
- empty 特殊的类,用来标记default属性或者注释annotation属性的空值
- kind 实参如何绑定到形参,就是形参的类型
- POSITIONAL_ONLY,值必须是位置参提供
- POSITIONAL_OR_KEYWORD,值可以作为关键字或者位置参数提供
- VAR_POSITIONAL,可变位置参数,对应*args
- KEYWORD_ONLY,keyword-only参数,对应*或者*args之后的出现的非可变关键字参数
- VAR_KEYWORD,可变关键字参数,对应**kwargs
举例:
import inspect
def add(x:int,y:int,*args,**kwargs)->int:
return x+y
sig = inspect.signature(add)
print(sig)
print('params : ', sig.parameters)
print('return : ', sig.return_annotation)
print('~~~~~~~~~~~~~~~~')
for i,item in enumerate(sig.parameters.items()):
name,param = item
print(i+1,name,param.annotation,param.kind,param.default)
print(param.default is param.empty, end = '\n\n')
有函数如下:
def add(x,y:int=7) -> int:
return x + y
- 检查用户输入是否符合参数注解的要求?
- 思路:
- 调用时,判断用户输入的实参是否符合要求
- 调用时,用户感觉上还是在调用add函数
- 对用户输入的数据和声明的类型进行对比,如果不符合,提示用户
def check(fn):
def wrapper(*args,**kwargs):
sig = inspect.signature(fn)
params = sig.parameters
values = list(params.values())
#print(values)
for i,p in enumerate(args):
# print(i,p)
params = values[i]
#print(params.annotation,params.empty)
if params.annotation is not params.empty and not isinstance(p,params.annotation):
print(p,'!==',values[i].annotation)
for k,v in kwargs.items():
if sig.parameters[k].annotation is not inspect._empty and not isinstance(v,sig.parameters[k].annotation):
print(k,v,'!===',sig.parameters[k].annotation)
return fn(*args,**kwargs)
return wrapper
@check
def add(x,y:int=7) -> int:
return x + y
#print(add(20,10))
print(add(20,y=10))
print(add(y=10,x=20))
python 类型注解的更多相关文章
- Python3.6引入的f-string 与 Python 3的新的特性:类型注解;
f-string 1.介绍 f-string(formatted string literals):格式化字符串常量,是Python3.6新引入的一种字符串格式化方法,使格式化字符串的操作更加简便. ...
- Python入门篇-类型注解
Python入门篇-类型注解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数定义的弊端 1>.动态语言很灵活,但是这种特性也是弊端 Python是动态语言,变量随时可 ...
- Python 3 新特性:类型注解——类似注释吧,反正解释器又不做校验
Python 3 新特性:类型注解 Crossin 上海交通大学 计算机应用技术硕士 95 人赞同了该文章 前几天有同学问到,这个写法是什么意思: def add(x:int, y:int) - ...
- Python Type Hint类型注解
原文地址:https://realpython.com/python-type-checking/ 在本指南中,你将了解Python类型检查.传统上,Python解释器以灵活但隐式的方式处理类型.Py ...
- 介绍几款 Python 类型检查工具
近日,微软在 Github 上开源了一个 Python 静态类型检查工具:pyright ,引起了社区内的多方关注. 微软在开源项目上的参与力度是越来越大了,不说收购 Github 这种大的战略野心, ...
- 字符串格式的方法%s、format和python3.6新特性f-string和类型注解
一.%s msg = '我叫%s,今年%s,性别%s' %('帅哥',18,'男') print(msg) # 我叫帅哥,今年18,性别男 二.format # 三种方式: # 第一种:按顺序接收参数 ...
- Python3新特性 类型注解 以及 点点点
Python3新特性 类型注解 以及 点点点 ... Python3 的新特性 Python 是一种动态语言,变量以及函数的参数是 不区分类型 的 在 函数中使用类型注解 相当于 给 形参的 类型 设 ...
- typing类型注解库
简介 动态语言的灵活性使其在做一些工具,脚本时非常方便,但是同时也给大型项目的开发带来了一些麻烦. 自python3.5开始,PEP484为python引入了类型注解(type hints),虽然在p ...
- python类型检测最终指南--Typing模块的使用
正文共:30429 字 预计阅读时间:76分钟 原文链接:https://realpython.com/python-type-checking/ 作者:Geir Arne Hjelle 译者:陈祥安 ...
随机推荐
- 9 loader - 分析webpack调用第三方loader的过程
注意:webpack处理第三方文件类型的过程: 1.发现这个要处理的文件不是JS文件,然后就去配置文件中,查找有没有对应的第三方loader规则 2.如果能找到对应的规则,就会调用对应的loader处 ...
- MySQL远程连接不上的解决方法
这篇文章主要为大家详细介绍了MySQL远程连接不上的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 之前遇到过MySQL本地可以连接但是远程连不上的问题,没有记录,今天在云上新申请的服 ...
- springcloud服务提供producer and 服务调用consumer
---------------------------------producer------------------------------------------- 1.pom文件中,作为客户端的 ...
- BZOJ 2277 strongbox (gcd)
题意 有一个密码箱,0到n-1中的某些整数是它的密码. 且满足,如果a和b都是它的密码,那么(a+b)%n也是它的密码(a,b可以相等) 某人试了k次密码,前k-1次都失败了,最后一次成功了. 问:该 ...
- bootstrap Table 的使用方法
然后添加css 找到bootstrap-table.min.css 添加进去 再添加JS Js添加时 按照顺序添加 然后初始化bootstrap-table <script type=&qu ...
- Oracle 绑定变量窥视
绑定变量窥视功能是数据库的一个特性,自ORACLE9i版本开始引入,默认是开启的. “绑定变量窥视”表示,查询优化器在第一次调用游标时,会观察用户定义的绑定变量的值,允许优化器来确认过滤条件的选择性, ...
- spring-AMQP-RabbitMQ
1.spring整合rabbitMQ配置文件 rabbitmq-context.xml <beans xmlns="http://www.springframework.org/s ...
- bzoj 3629
给出数 $n$记 $f(x)$ 表示 $x$ 的因子和求出所有 $x$ 使得 $f(x) = n$考虑 $x = p_1 ^{a_1} * p_2 ^ {a_2} * \cdots * p_k ^ { ...
- 04_Logstash安装
Logstash部署 1.部署JDK环境 2.下载Logstash源码包 $ wget https://artifacts.elastic.co/downloads/logstash/logstash ...
- Linux下MySQL的操作(最全)
注意:这里以mariadb为例 启动mysql服务 systemctl start mariadb 登录mysql mysql -u root -p SQL语言分类 - 数据定义语言:简称[DDL]( ...