1、函数定义的弊端:

Python是动态语言,变量随时可以被赋值,且能赋值为不同的类型。

Python不是静态编译型语言,变量类型是在运行器决定的

动态语言很灵活,但是这种特性也是弊端:

 def  add(x, y):return x +yadd(1, 2)add('a', 'b') 都是ok的,但是不是自己想要的,只是数学加

难发现:由于不做任何类型检查,知道运行期间问题才会显现出来,或这上线运行时才能暴露出问题

难使用:函数的使用者看到函数的时候,并不知道你的函数的设计,并不知道应该传入什么类型的数据

2、如何解决这种动态语言定义的弊端

增加文档字符串

这只是一个 管理,不是强制标准,不能要求程序员一定为函数提供说明文档。

函数定义更新了,文档未必同步更新

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def add(x, y):''':param x::param y::return:'''return  x + y
print(help(add))

3、函数注解 Function Annotations

举例 1:

函数注解总结:

Python3.5 引入的
对函数的参数进行类型注解
对函数的返回值进行类型注解
只对函数参数做一个辅助的说明,并不对函数的参数进行类型检查
提供第三方工具,做代码分析,如上所述的Pycharm
函数注解的信息,保存在__annotations__ 属性中
print(add.annotations) # {‘x’: <class ‘int’>, ‘y’: <class ‘int’>, ‘return’: <class ‘int’>} # 是有序的字典,3.6 之后

变量注解:

Python 3.6 引入的 i : int = 3

4、业务应用:

函数参数检查:

思路:

函数的参数的检查,一定是在函数外
函数应该作为参数,传入到检查的函数中
检查函数拿到函数传入的时间参数与形参声明对比。
__annotations__属性是一个字典,其中包括返回值类型的声明,假设要做位置参数的判断,无法和字典中的声明对应,使用inspect模块。

inspect模块:

提供获取对象信息的函数,可以经检查函数 和 类 , 类型检查。

5、inspect 模块

# NO 1 引入inspect 模块,获取函数 签名 以及 参数(形参) 类型注解# inspect.isfunction(object) 是否是函数
# inspect.isclass(object) 是否是类
# inspect.ismethod() 是否是类的方法
# inspect.isfunction() 是否是函数
# inspect.isgenerator() 是否是生成器对象
# inspect.isgeneratorfunction() 是否是生成器函数
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import  inspectdef add(x:int, y:int) -> int:# 返回值的注解return  x + yprint(add.__name__) # 返回的是 str类型 ‘add'print(inspect.isfunction(add)) # True 是函数,可以用来判断sig = inspect.signature(add)
print(sig) # (x: int, y: int) -> int 签名print(add.__annotations__,'---------')# {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>} ---------params = sig.parameters # 获取参数,以及参数类型注解
print(params) # OrderedDict([('x', <Parameter "x: int">), ('y', <Parameter "y: int">)])
# 3.6之后使用了有序字典,所以是有顺序的!!!
# 注意 key 是字符串,并不是形参的标识符,并不是把形参str(x) 这是不对的!这是把x对应的值给类型转换,并不是'x'
# 基本概念要清楚!# 参数类型 (内置的一种新类型)
for i, (k,param) in enumerate(params.items()):print(i,k, param)
#     from inspect import Parameter
#     param:Parameter ##变量类型注解,在pycharm 中就可以用 点 就可以获取下拉列表# 上面的这两句只是为了获取 属性,免得去查 帮助,即:参数类型 的 属性print(param.name, param.default, param.annotation, param.kind)
# 0 x x: int
# x <class 'inspect._empty'> <class 'int'> POSITIONAL_OR_KEYWORD
''' x 是 参数名----默认值是 空--------参数的属性注解 -------形参类型 位置参数或者关键字'''
# 1 y y: int
# y <class 'inspect._empty'> <class 'int'> POSITIONAL_OR_KEYWORDprint('+' , params['x'].annotation)
print('+' , params['x'])def a(*args, **kwargs): # args 只有名字 和passsig = inspect.signature(a)
print(sig)
params = sig.parameters
print(params)
for k,v in params.items():print(v.name,v.default,v.annotation,v.kind)
# (*args, **kwargs)
# OrderedDict([('args', <Parameter "*args">), ('kwargs', <Parameter "**kwargs">)])
# args <class 'inspect._empty'> <class 'inspect._empty'> VAR_POSITIONAL
# # kwargs <class 'inspect._empty'> <class 'inspect._empty'> VAR_KEYWORD

signature(callable) 获取签名(函数签名包含了一个函数的信息,包括函数名,他的参数类型,它所在的类和命名空间及其他信息)

Parameter 对象:

保存在元组中,是只读的
name,参数名字
annotation,参数的直接,可能没有定义
default,参数的缺省值,可能没有定义
empty,特殊的类,用来标记default 属性或者注释annotation属性的空值
kind,实参如何绑定到形参,值必须是位置参数提供
POSITION_ONLY 值必须是位置参数提供,事实上,python中没有,被下一项包括
POSITION_OR_KEYWORD 值可以作为关键字或者位置参数提供
VAR_POSITIONAL 勒边位置参数,对应args
KEYWORD_ONLY 对应
或者*args之后出现的非可变关键字参数
VAR_KEYWORD 可变关键字参数,对应**kwargs

6、参数检查的实现

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
NO 2 类型检查
import inspect
import timedef check(fn):def wrapper(*args, **kwargs):sig = inspect.signature(fn) # 签名params = sig.parameters # 有序字典values = list(params.values()) # 参数类型flag = Truefor i,x in enumerate(args):param:Parameter = values[i]if not isinstance(x, param.annotation):print(x,'not')flag = False #只要发现一个就不要往后了else:print(x,'ok')if not flag:raise  TypeError('sssss')return fn(*args, **kwargs)return wrapper@check
def add(x:int, y:int=6) -> int:return x + yadd(4,5)
# 4 ok
# 5 ok# NO2
import inspect
import timedef check(fn):def wrapper(*args, **kwargs):sig = inspect.signature(fn) # 签名params = sig.parameters # 有序字典values = list(params.values()) # 参数类型flag = Truefor i,x in enumerate(args):param:Parameter = values[i]if not isinstance(x, param.annotation):print(x,'not')flag = False #只要发现一个就不要往后了else:print(x,'ok')for k,v in kwargs.items():param: Parameter = params[k]# 如果参数注解为空 inspect._empty 或者写成 param.emptyif param.annotation != inspect._empty and not isinstance(v, param.annotation):print(v, 'not---')else:print(v, 'ok-----')# if not flag:#     raise  TypeError('sssss')return fn(*args, **kwargs)return wrapper# @check
# def add(x, y:int=6) -> int:
#     return x + y
#
#
# add(x=4,y=5)
# # 4 ok-----
# # 5 ok-----# @check
# def add(x:int, y:int=6) -> int:
#     return x + y
#
#
# add(4,y=5)
# # 4 ok
# # 5 ok-----
#
# @check
# def add(x:str, y:int=6) -> int:
#     return x + y
#
#
# add(4,y=5)
# # 4 not
# # 5 ok-----

补:insect 的is 函数

inspect.ismodule(object)
Return true if the object is a module.inspect.isclass(object)
Return true if the object is a class, whether built-in or created in Python code.inspect.ismethod(object)
Return true if the object is a bound method written in Python.inspect.isfunction(object)
Return true if the object is a Python function, which includes functions created by a lambda expression.inspect.isgeneratorfunction(object)
Return true if the object is a Python generator function.inspect.isgenerator(object)
Return true if the object is a generator.inspect.iscoroutinefunction(object)
Return true if the object is a coroutine function (a function defined with an async def syntax).New in version 3.5.inspect.iscoroutine(object)
Return true if the object is a coroutine created by an async def function.New in version 3.5.inspect.isawaitable(object)
Return true if the object can be used in await expression.Can also be used to distinguish generator-based coroutines from regular generators:New in version 3.5.inspect.isasyncgenfunction(object)
Return true if the object is an asynchronous generator function, for example:New in version 3.6.inspect.isasyncgen(object)
Return true if the object is an asynchronous generator iterator created by an asynchronous generator function.New in version 3.6.inspect.istraceback(object)
Return true if the object is a traceback.inspect.isframe(object)
Return true if the object is a frame.inspect.iscode(object)
Return true if the object is a code.inspect.isbuiltin(object)
Return true if the object is a built-in function or a bound built-in method.inspect.isroutine(object)
Return true if the object is a user-defined or built-in function or method.inspect.isabstract(object)
Return true if the object is an abstract base class.inspect.ismethoddescriptor(object)
Return true if the object is a method descriptor, but not if ismethod(), isclass(), isfunction() or isbuiltin() are true.

Python-类型注解(3.5引入)相关推荐

  1. python 类型注解 list_Python 类型注解

    说明 Python 教程正在编写中,欢迎大家加微信 sinbam 提供意见.建议.纠错.催更. 简单说,Python 类型注解功能可以让我们的代码更加易读,从而达到编写更加健壮的代码目标.类型注解又叫 ...

  2. ​Python 3 新特性:类型注解——类似注释吧,反正解释器又不做校验

    ​Python 3 新特性:类型注解 Crossin ​ 上海交通大学 计算机应用技术硕士 95 人赞同了该文章 前几天有同学问到,这个写法是什么意思: def add(x:int, y:int) - ...

  3. python Typing模块-类型注解

    写在篇前   typing 是python3.5中开始新增的专用于类型注解(type hints)的模块,为python程序提供静态类型检查,如下面的greeting函数规定了参数name的类型是st ...

  4. Python Type Hint类型注解

    原文地址:https://realpython.com/python-type-checking/ 在本指南中,你将了解Python类型检查.传统上,Python解释器以灵活但隐式的方式处理类型.Py ...

  5. [转]关于Python里的类型注解

    我们知道 Python 是一种动态语言,在声明一个变量时我们不需要显式地声明它的类型,例如下面的例子: a = 2print('1 + a =', 1 + a) print('1 + a =', 1 ...

  6. Python 3 新特性:类型注解

    Python 3 新特性:类型注解 之前也看到这种写法,有人疑惑这个写法是什么意思: def add(x:int, y:int) -> int:return x + y 我们知道 Python ...

  7. 《流畅的Python第二版》读书笔记——函数中的类型注解

    引言 这是<流畅的Python第二版>抢先版的读书笔记.Python版本暂时用的是python3.10.为了使开发更简单.快捷,本文使用了JupyterLab. 本章关注于Python在函 ...

  8. 介绍一款python类型检查工具pyright

    介绍 近日,微软在 Github 上开源了一个 Python 静态类型检查工具:pyright ,引起了社区内的多方关注. 微软在开源项目上的参与力度是越来越大了,不说收购 Github 这种大的战略 ...

  9. python类型检测最终指南--Typing的使用

    点击上方蓝字关注 正文共:30429 字 预计阅读时间:76分钟 原文链接:https://realpython.com/python-type-checking/ 作者:Geir Arne Hjel ...

  10. python参数注解

    函数定义的弊端: python是动态语言,变量随时可以被赋值,且能赋值为不同的类型,动态语言很灵活,但是这种特性也是弊端 难发现:由于不做任何类型检查,直到运行期问题才显现出来,或者线上运行时才能暴露 ...

最新文章

  1. Maya基础入门学习教程
  2. linux program HEAP tracker
  3. 公共的service接口
  4. 2010年度报告:是谁在编写Linux内核?
  5. eclipse开发javaweb项目配置tomcat
  6. c语言第一次作业,C语言培训班第一次作业 (1)
  7. 在嵌入式公司和在互联网公司写软件,有什么区别?
  8. mvc 怎么把后台拼接好的div写到前台_MVC 从后台页面 取前台页面传递过来的值的几种取法...
  9. 改变外观_“改”出来的精彩!盘点5种改变葫芦外观的技艺
  10. 机器学习算法总结之支持向量机(一)
  11. 分享17个网页设计中字体排版的优秀示例
  12. 用VS2013编译FFMPEG232
  13. 模型选择 + 过拟合和欠拟合 动手学深度学习v2 pytorch
  14. 分布式数据库系统原理(第三版)pdf
  15. python 点分十进制IP地址转16进制字符串
  16. python无头浏览器截图_selenium3使用谷歌无头浏览器、截图
  17. 通信原理(张祖凡)知识点归纳【持续更新】
  18. 大三开学,百度面试感受
  19. 《网络安全等级保护基本要求》(GB/T 22239-2019)标准解读
  20. 简单几行代码带你爬取王者荣耀皮肤

热门文章

  1. nagios新添加服务有时显示,有时不显示问题解决
  2. *** 隧道和加密技术知识要点
  3. 也玩有道难题的双立方数问题:Python 版解法
  4. Smartform下載PDF
  5. POPUP_TO_DECIDE
  6. 共赴CIO时代,永洪BI如何推动企业数字化转型与创新?
  7. 不起眼的夫妻店,为何会被阿里、京东、苏宁同时盯上?
  8. 百度2020Q3财报:“十四五”规划注入新动能,百度智能云驶入快车道
  9. 从第一碗粉到云手机,天心很行
  10. vb不能插入png图片_第16节-图片 | 剑雨Axure RP9系列「基础」