2019/10/10 01-类型注解

类型注解本来没有,是python3.5慢慢引入的,就是为了解决动态语言的弊端
静态语言就是静态编译型语言
动态语言并不需要事现申明,这种变量是什么类型的,静态语言是必须申明,动态语言不需要申明,什么时候赋值,什么时候就定义出来,是什么类型,赋值什么类型就是什么类型,只要是合法的
动态语言并不能实现知道你的函数形参是什么类型
就比如函数add,传字符也行,传数字也可以,动态语言是根本没办法约定这个事情的,也就是用户在使用的时候根本不知道自己该写什么,就是可以从文档字符串告诉它
但是文档字符串不是一种语言的强制性约束,只是一个说明
(在运行时,要大量的操作,来判断是否参数是你所要求的),但是静态编译型语言就不需要这么做,在写函数的时候,就给你约定好,此函数的形参是什么类型,编译的时候就会给你报错了,还没运行

python如果没按照要求,编译是不会出错的,放在线上运行才会报错,但是python学习静态编译型语言,在你定义函数的时候,可以在函数的形参上标注类型,此类型不做强制性约束(但是java,c++不行,只要你标注int这样,你就只能传这样的)编译时就进行类型的校对,这是静态编译型语言的特征
动态语言是随你用,出错再说
在这里插入图片描述
python是动态语言,还是强类型语言,势必有弊端
好处是自由,可以适用多种类型,但是就因为适用多种类型,才导致写的程序跟你预期的不一样,静态语言就必须定义这个x,y是什么类型
python就必须扔到解释器跑起来,出错了才给你抛出异常,后知后觉的代价太高

强类型语言就不允许这两个混加
在这里插入图片描述
这种就属于跳出了使用范围在这里插入图片描述
万一传的不符合要求,如果处理不好就整个程序都崩溃了

上线运行才出来就太晚了,代价太高,不做约束就需要用你没想到的方式做测试,才能报错
在这里插入图片描述

使用者你去使用也不知道返回什么类型,也不知道传什么类型,有时候很难看到函数的具体设计者是什么意思,所以很难传入一个正确的东西
在这里插入图片描述
所以3.5引入参数注解,3。6引入变量注解

以前就是这么写,(很多项目都是一个函数十几个版本,因为新来的不知道老的写的是什么用,没有注释,就自己写,久而久之项目可能就失控了)
在这里插入图片描述
上面的文档如果更新不及时,就出问题,python就在3.5更新了参数的注解。,主要是注解参数,还把函数注解了
告诉你x 是int y是int 返回值是int,就知道是做整形的加法

在这里插入图片描述
pyhon学习了变态编译型语言的特别,约束了参数是谁,但是python不做强制性约束,静态编译型语言是做强制性约束的,python只是告诉你,假如你声称int,就信你了
在这里插入图片描述
这样表示返回值是int,但是执行照样没有影响
在这里插入图片描述
换到pycharm来试试,第7行有颜色变化,但是notebook里没有变化,
是不做强制性约束,这些编辑器利用这个特性做了一定的检查工作,但是这种检查不是强制的,颜色改变告诉你,你没有按照约定来,但是不强制,注解是不强制的

在这里插入图片描述
没有return,颜色才变
在这里插入图片描述
是字符串,颜色就变了
在这里插入图片描述
a=none,就告诉你是不对的
在这里插入图片描述
如果把返回值参数注解去掉,就没有影响了
在这里插入图片描述在这里插入图片描述
哪个变量加申明由你定在这里插入图片描述提示你list这种类型没有add方法
在这里插入图片描述
这样就会报错,因为list根本没有add方法
在这里插入图片描述
就等于在运行的时候才会抛出异常
在这里插入图片描述
这样的代码如果上线,这样的数据一来,送进去不符合要求就报错了

还有个好处,先直接写x.点
在这里插入图片描述
改成list,加点,list该有的方法都有,所以现在推荐写的时候,把函数的参数注解加上去,不然你怎么知道加什么类型,如果是不认识库的,函数没有注解,你都不知道该怎么用
注解加上去,发现要的方法都在这

在这里插入图片描述
append函数返回none,就地修改返回none
在这里插入图片描述

pycharm提供了,你有参数注解,会替你进行简单的参数检查,文档字符串,会把参数列在下面在这里插入图片描述
但是什么类型需要自己写,不过第一行写函数做什么作用
在这里插入图片描述
不过这叫参数注解或者函数注解
在这里插入图片描述
在这里插入图片描述
函数注解可以对函数的参数进行类型注解,对函数的返回值进行类型注解,
是个说明性的,不对形参和返回值做任何强制约束(有些类似pycharm的工具,帮我们进行类型的检查,这种也是个提醒也不是强制性的)
只对函数参数做一个辅助的说明,并不对函数参数进行类型检查
提供给第三方工具,做代码分析,发现隐藏的bug(让程序员提前发现问题)
这些函数的注解信息,放在函数对象的__annotations__属性中

在这里插入图片描述
查看类型,这个dict式个特殊的,明确告诉你是有顺序的
在这里插入图片描述
写个返回值是none,return总是在最后的
在这里插入图片描述
改成str在这里插入图片描述在这里插入图片描述
在3.6之前是不能这么写,相当于定义a的变量类型是什么
在这里插入图片描述
就是只做申明,至于照不照这个约定来,由你决定
在这里插入图片描述
但是函数传入的参数应该是某些类型,以方便你来完成功能,不应该是随便给的,不然设计的初衷是有出入的,要求大家应该使用类型,这个时候用注解就比较合适,返回值的类型也很重要,标注返回值的类型是什么将会更好,看的比较清楚

在这里插入图片描述
上面定义的函数你确定你要覆盖,这是一种善意的提醒在这里插入图片描述
参数注解可以让你进行类型的检查的
pycharm工具是可以给我们做一些提醒的,如果送入的参数不对,做的提醒仅限于颜色不同(但是如果参数不对,让函数不能执行岂不更好)

定义时时每什么可以检查的,在你调用函数,传入实参的时候才开始检查,函数调用的时候,形参配上实参传过来的数据,然后函数开始压栈,然后局部变量开始压栈,(能否再这个时候做一些事情,我们去拦截,如果再函数调用之前拦截一下, 把参数检查一下,对不对,严重就警告,不严重就提醒你传的参数不对)

检查是一个功能,再函数调用之前做的,比如检查

在这里插入图片描述
** __annotations__是个普通的字典,刚好用的时候再3.6,就跟顺序相关,3.5之前时跟顺序无关的,所以要借助一个模块,inspect(体格获取对象信息的函数,可以检查函数和类,类型检查)**
形参只是一种注解,告诉它未来要这么用,真正用的时候就传入实参的时候,要跟形参注解的时候的类型要进行对比,
类型一致通过,不一致报错
使用isinstance,type()==也可以

在这里插入图片描述
fucntion有doc属性,annotations刚好放的时注解信息在这里插入图片描述
生成器
在这里插入图片描述
有一大堆判断,是模块吗,是类吗,是方法吗(如果是类里面的叫method方法),是函数吗(callable可调用对象很多,不一定是函数)在这里插入图片描述
是不是生成器函数,是不是生成器对象
iscoroutinfunction是不是协程函数
is coroutine是不是协程对象
在这里插入图片描述
能不能拿到一个签名在这里插入图片描述
函数定义,里面有签名,拿到签名,在这里插入图片描述
用b这个名称找定义,是个字典,返回告诉你b这个变量用的是整型
在这里插入图片描述
在这里插入图片描述
是不是生成器对象
在这里插入图片描述
是不是生成器函数
在这里插入图片描述
查看什么是签名,就是上面定义的东西
在这里插入图片描述
拿到参数列表
是个有序字典,3.5的annotations不是有序的,为了拿到这个参数列表,返回有序字典

在这里插入图片描述在这里插入图片描述
**这是一个函数签名,前面就是函数申明定义的这一块,里面属于函数实现了,叫语句体,签名跟我们的形参有关,参数集合拿到字典来封装,为了保证顺序用了一个有序字典orderedDict
**
在这里插入图片描述
有序字典的key是字符串,但是你写的形参就不是,到最后你写的形参一定要有个名字就是字符串
在这里插入图片描述
这是把x变量对应的值进行转换
在这里插入图片描述
x表示个变量,变量的名称往往是个字符传,函数的名称打印出来也是字符串,func__name,而标识符是赋什么值就是什么类型,函数定义以后,函数对象给标识符赋值
但是标识符赋值什么类型就是什么类型

在这里插入图片描述
拿到参数后就可以进行检查了,应该在调用时检查,那么在调用时候怎么拦截,定义个check函数,能对函数进行检查
写成这样没用,不让人察觉到就需要用到装饰器

在这里插入图片描述
装饰器函数需要放在前面,因为用的时候需要已经定义好的
在这里插入图片描述
但是昨天的logger的例子,还需要在里面写,解决包装的函数,你是被包装函数
包装函数里面就进行类型检查

在这里插入图片描述
其实把这一块内容拿到上面就可以做参数检查了
在这里插入图片描述
通过inspect.signature获得前面,用这个方法对函数拿到一个签名
在这里插入图片描述
这个就是个类型
在这里插入图片描述
这个类型在构造的时候,需要签名列表,如果isnone就定义成什么东西,如果没有就定义这个,一般都是none进来,这样就可以拿到一个有序字典
在这里插入图片描述
在参数里 迭代得到之后会有两个东西,这么理解的话,是个有序的字典对它进行迭代,
拿到的时候key
在这里插入图片描述
自己试一下在这里插入图片描述在这里插入图片描述
这个参数缺省值还可以是空在这里插入图片描述
实际在定义的过程中,z这块可以不写,不写相当于注解没有
在这里插入图片描述
在这里插入图片描述
但是这个空代表一个特殊的变量是需要定义的
在这里插入图片描述
这个参数类型有个属性是空,每一个参数有自己的名字name
有自己的缺省值default
类型kind
注解annotation
在这里插入图片描述
在这里插入图片描述
打印一下看看
x相当于没有定义注解,y定义了
0 x x(0是索引)

在这里插入图片描述
两套表现形式,有注解,和没注解
在运行时明确告诉你是参数类型parameter

在这里插入图片描述
写代码的时候就推不出来不知道你是什么类型在这里插入图片描述
3.6就可以这么做
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
拿到3.6试一下,就有了
在这里插入图片描述

有些对象很复杂,查帮助都要查半天
类型就是inspect.parameter,就可以从 from inspect import parameter 从inspect模块导入parameter

在这里插入图片描述
用完就可以小时
在这里插入图片描述
在这里插入图片描述
参数名是x,缺省值是空的,annotation是列表,这里面位置和keyword都可以传参(positional or keyword)
在这里插入图片描述
这种语法脱离3.5就不支持了,建议把类型去掉,不建议部署3.5一下,不成熟
在这里插入图片描述
这样不行,改一下,刚才的技巧
这个不写也可以,上面的param相当于把变量已经定义过了

在这里插入图片描述相当于a=1,a ,这是不会有错的,a就相当于空语句,没有什么作用在这里插入图片描述
ctrl+左鼠标在这里插入图片描述
就跳转了
在这里插入图片描述
这个之前就见过
positional_only 仅位置
positional or keyword 位置和关键字
var_positional 可变位置
keyword_only
var_keyword 可变关键字
在这里插入图片描述
定义参数只能使用这些东西,想怎么组合就需要符合什么语法
positional_only 仅位置传参只是定义了,但是实际用不到

在这里插入图片描述
通过这个模块提供的函数就可以检查函数内部的东西,
如果没有param.default缺省值就显示为空 insepect_empty

在这里插入图片描述
在这里插入图片描述
把x注解去掉在这里插入图片描述
x后面的annotation也是空的了
在这里插入图片描述
没有值就都是inspect的空,点击一下在这里插入图片描述
这是一个类型
是inspect模块下的一个类型
在这里插入图片描述
通过签名拿到了整个定义的形式,从里面可以去拿参数字典,这块提供的参数字典是一个有序字典,有序字典的key是参数的名称,value是个参数对象
参数对象有4个重要属性,name(名字依然是字符串),default(缺省值没有就是empty,有就看你定义什么类型)
annotation(声称叫什么类型不定义就是empty,),kind(name和kind是必须有的,只要有一个形参在,参数类型就定义下来了,但是缺省值和注解爱给不给)

在这里插入图片描述
缺省值申明改成100试试
申明是str但是缺省值是100,因为是不做强类型检查的

在这里插入图片描述
帮助文档说的很清楚,里面有什么
在这里插入图片描述
在这里插入图片描述
签名
在这里插入图片描述
告诉你签名类型
在这里插入图片描述
签名类型对象,可以调参数属性,这是个有序字典
在这里插入图片描述
返回值在专门的return_annotation里,annotation如果返回值没有指定不加 ->箭头就是empty
这个关注的少,主要还是看parameter
为什么返回值不指定有可能计算返回数字,但是报错就返回字符串,有时候合法返回是个字符串,不合法就返回一个none

在这里插入图片描述
注解都是非强制性约束,爱返回什么返回什么
在这里插入图片描述
在部署的时候都有基本要求,必须python用什么版本,因为低了可能库就没有,或者语法就报错

有序字典也是字典,能通过key访问
在这里插入图片描述
参数类型有4中类型,annotation是其中一个,name,kind,default
在这里插入图片描述
这两个不能定义缺省值和类型,都是empty,但是有key,(name,kind)
在这里插入图片描述
可以判断是什么类型在这里插入图片描述
判断print是否是内建函数
在这里插入图片描述
这个parameter对象有,name参数名,kind形参的类型,annotation参数注解,default缺省值,empty特殊的类型在这里插入图片描述
没有仅仅是位置参数的东西在这里插入图片描述在这里插入图片描述在这里插入图片描述
name恰好是后面item的name
在这里插入图片描述在这里插入图片描述
最好的是用装饰器
在这里插入图片描述在这里插入图片描述
首先拿到签名在这里插入图片描述
拿到签名也就是有序字典就可以对参数进行处理
灰色代表从来没使用过
导入语句可以放在代码中的任意一部分,但习惯上放在第一

在这里插入图片描述
因为没有return wrapper,这个wrapp现在就没人使用
在这里插入图片描述
改成wrapper在这里插入图片描述
notebook适合测试,pycharm工具适合开发
在这里插入图片描述在这里插入图片描述
有时候你起的名字可能跟系统库里的变量冲突了在这里插入图片描述
注解int,返回也是int,最简单的函数
在这里插入图片描述
只要你传实参都做检查
在这里插入图片描述
4,5就随着这个传进来了
在这里插入图片描述
4.5检查,就要看你的代码对不对
遍历args参数
类型是放在value部分的,用key来找到values,key是有序的,你拿的时候item也是有序的
在这里插入图片描述
annotation放的是注解定义,返回的是类型,不是字符串
在这里插入图片描述
如果你不是annotation这个类型就跟我们声明的不一致在这里插入图片描述
查看是否满足需要
拿签名,拿参数列表,是个有序字典,拿到后,把value有序地摘出来

在这里插入图片描述
4进来跟这个进行对比,5进来进行对比在这里插入图片描述
加个ok在这里插入图片描述
在这里插入图片描述
如果改成str,就是not,但是该怎么调用还是怎么调用
在这里插入图片描述
其实可以做个标记,flag本来是true,发现错误就是false,就break没必要检查了。下面if就需要做些事情了

在这里插入图片描述
现在可以抛出异常
在这里插入图片描述在这里插入图片描述
如果用的是关键字传参,走的就是kwargs
在这里插入图片描述
这样检查就进不去了
在这里插入图片描述
kwargs还是需要的
有key找value部分的参数定义

在这里插入图片描述
key是参数名,v是参数类型(有4个属性,name,kind,default,annotation

在这里插入图片描述
跟上面其实是一个意思在这里插入图片描述在这里插入图片描述
假如现在这么写在这里插入图片描述
x的类型定义和缺省值都为空在这里插入图片描述
这两个是一个东西
在这里插入图片描述
如果不等于空且
如果参数的注解不等于空而且不符合它的要求

在这里插入图片描述
关键字也是一样的在这里插入图片描述
执行一下在这里插入图片描述
传4也是ok在这里插入图片描述
数据结构在这里是大量使用在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
两种调用方式,写成装饰器也可以
标红的本质上是同一个东西,一个是遍历args,一个是遍历kwargs.items
这里面最麻烦的就是用位置参数怎么对应的问题,顺序一样就可以用同一个索引来比较了

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值