深入浅析Python 函数注解与匿名函数


Posted in Python onFebruary 24, 2020

函数注解与匿名函数

关于函数参数的定义,调用以及函数参数的内容,在下面的文章中已经做了初步的介绍,有需要的可以访问进行了解:

函数注解

在编写函数,当下肯定清楚函数如何使用的。若是函数较为复杂,过段时间,编写者有可能需要花一段时间去重新了解函数的使用,那其他使用者也同样会遇到这样的困惑。

所以当编写完函数后,可以为函数的参数添加一些额外的信息。这里给函数参数添加注解,能够提示程序员如何正确使用这个函数。如下示例:

def add(x:int, y:int) -> int:
 '''Returns the sum of two numbers
 '''
 return x + y

在这里,Python 解释器并不会对这些注解添加任何的语义(可能第三方工具和框架会)。它们并不会被类型检查,运行的时候跟没有添加注解前是没有任何差距的。但若是有需要的人阅读源码时,这些都能给阅读者提供帮助。同时会出现在文档里。

>>> help(add)
Help on function add in module __main__:

add(x: int, y: int) -> int
 Returns the sum of two numbers

函数注解只存储于函数的 __annotations__ 属性中。比如:

>>> add.__annotations__
{'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}

注解的主要用途还是文档。Python 并没有类型声明,当阅读源码的时候,比较难知道传递什么样的参数给这个函数。这时候,注解就能够给阅读者更多的提示,能够让他们正确使用函数。

匿名函数

如何定义

在前面提及的文章中,讲到了使用 def 定义一个函数。但若是函数能够单行实现,这个时候可以考虑使用匿名函数(lambda 表达式)来实现这种功能。

当函数功能非常简单,仅仅只是计算一个表达式的值时,就可以用 lambda 表达式来替代。比如:

>>> add = lambda x, y: x + y
>>> add
<function <lambda> at 0x0000021496CD98B8>
>>> add(2, 3)
5
>>> add('hello', ' world')
'hello world'

其实使用 lambda 表达式跟下面的效果是一样的:

>>> def add(x, y):
... return x + y
...
>>> add(2, 3)
5
>>> add('hello', ' world')
'hello world'

lambda 表达式主要运用的场景是排序或者数据 reduce:

>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> sorted(pairs, key=lambda pair: pair[1])
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

上面的例子就是用于排序列表元素,以列表元素元组的第二个元素进行排序。此处的元组的第二个元素是字符串,关于字符串的比较,先比较字符串的首字符,首字符相同时,比较第二个字符,以此类推。

在这里, four 与 one , f 比 o 排序更前,所以 four 排在 one 前面, three 和 two 首字符相同,比较的是第二个字符 h 和 w ,所以 three 排在 two 前面。

尽管 lambda 表达式能够定义简单函数,但其实是有限制的。只能指定单个表达式,它的值就是最后返回的值。即是不能包含其他的语言特性,包括多个语句、迭代以及异常处理等等。

捕获变量值

如何在定义匿名函数时捕获某些变量的值?现在,先看看以下示例代码的效果:

>>> x = 10
>>> a = lambda y: x+y
>>> x = 20
>>> b = lambda y: x+y

在这里,先猜猜 a(10) 和 b(10) 的结果?若觉得结果是 20 和 30 ,那就错了:

>>> a(10) 30 >>> b(10) 30

产生上面的结果,是因为 lambda 表达式中的 x 是一个自由变量,它是在运行的时候绑定值,而不是在定义的时候就绑定,这里跟函数的默认值参数定义是不同的。因此,在调用这个 lambda 表达式时, x 的值其实是执行时的值。例如:

>>> x = 10 >>> a(10) 20 >>> x = 20 >>> b(10) 30

若是向在匿名函数在定义时就捕获值,可以将参数值定义为默认参数:

>>> x=10 >>> a = lambda y, x=x: x+y >>> x=20 >>> b = lambda y, x=x: x+y >>> a(10) 20 >>> b(10) 30

还有一个需要注意:假如想用循环或列表推导创建一个 lambda 表达式列表,期望函数能够在定义时就记住每次的迭代值。以下的写法是无法达到效果的:

>>> func = [lambda x: x+n for n in range(5)] >>> for f in func: ... print(f(0)) ...

这里最终执行的结果,也是因为最终执行,n 的值其实是迭代的最后一个值。

修改函数,使其达到想要达到的效果,也是上面提及的默认值的做法:

>>> func = [lambda x, n=n: x+n for n in range(5)] >>> for f in func: ... print(f(0)) ...

现在使用默认值参数的形式,就能够实现在定义时绑定所需的值。

参考资料

来源

[1] David M. Beazley;Brian K. Jones.Python Cookbook, 3rd Edtioni.O'Reilly Media.2013.

[2] "4.7.6 Lambda Expressions".docs.python.org.Retrieved 23 February 2020.

总结

到此这篇关于Python 函数注解与匿名函数的文章就介绍到这了,更多相关Python 函数注解与匿名函数内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python统计日志中每个IP出现次数的方法
Jul 06 Python
Python+django实现简单的文件上传
Aug 17 Python
python抽取指定url页面的title方法
May 11 Python
对python制作自己的数据集实例讲解
Dec 12 Python
对Python3中dict.keys()转换成list类型的方法详解
Feb 03 Python
python 获得任意路径下的文件及其根目录的方法
Feb 16 Python
​如何愉快地迁移到 Python 3
Apr 28 Python
利用python开发app实战的方法
Jul 09 Python
python梯度下降算法的实现
Feb 24 Python
Python字典fromkeys()方法使用代码实例
Jul 20 Python
基于opencv实现简单画板功能
Aug 02 Python
django上传文件的三种方式
Apr 29 Python
python数据预处理方式 :数据降维
Feb 24 #Python
python实现PCA降维的示例详解
Feb 24 #Python
Python sklearn库实现PCA教程(以鸢尾花分类为例)
Feb 24 #Python
python 线性回归分析模型检验标准--拟合优度详解
Feb 24 #Python
最小二乘法及其python实现详解
Feb 24 #Python
在Python 的线程中运行协程的方法
Feb 24 #Python
Python 爬取必应壁纸的实例讲解
Feb 24 #Python
You might like
PHP判断表单复选框选中状态完整例子
2014/06/24 PHP
PHP获取当前URL路径的处理方法(适用于多条件筛选列表)
2017/02/10 PHP
浅谈javascript 面向对象编程
2009/10/28 Javascript
基于jquery封装的一个js分页
2011/11/15 Javascript
js转化毫秒为时间格式代码
2014/04/10 Javascript
JavaScript实现检查页面上的广告是否被AdBlock屏蔽了的方法
2014/11/03 Javascript
如何编写高质量JS代码(续)
2015/02/25 Javascript
JavaScript函数使用的基本教程
2015/06/04 Javascript
jquery实现滑动特效代码
2015/08/10 Javascript
jQuery树形下拉菜单特效代码分享
2015/08/15 Javascript
AngularJS 面试题集锦
2016/09/06 Javascript
AngularJS删除路由中的#符号的方法
2016/09/20 Javascript
JS实现按钮颜色切换效果
2020/09/05 Javascript
vue-baidu-map 进入页面自动定位的解决方案(推荐)
2018/04/28 Javascript
JavaScript 正则命名分组【推荐】
2018/06/07 Javascript
详解vue-cli 脚手架 安装
2019/04/16 Javascript
JS实现水平遍历和嵌套递归操作示例
2019/08/15 Javascript
vue实现设置载入动画和初始化页面动画效果
2019/10/28 Javascript
Vue 请求传公共参数的操作
2020/07/31 Javascript
[35:39]完美世界DOTA2联赛PWL S2 FTD.C vs Rebirth 第二场 11.22
2020/11/24 DOTA
python 动态获取当前运行的类名和函数名的方法
2014/04/15 Python
python统计字符串中指定字符出现次数的方法
2015/04/04 Python
详细讲解用Python发送SMTP邮件的教程
2015/04/29 Python
快速解决安装python没有scripts文件夹的问题
2018/04/03 Python
python使用openpyxl库修改excel表格数据方法
2018/05/03 Python
在Python中使用Neo4j的方法
2019/03/14 Python
Django框架搭建的简易图书信息网站案例
2019/05/25 Python
浅谈Pytorch中的torch.gather函数的含义
2019/08/18 Python
Python学习笔记之列表和成员运算符及列表相关方法详解
2019/08/22 Python
利用Python如何制作贪吃蛇及AI版贪吃蛇详解
2020/08/24 Python
创业资金计划书
2014/02/06 职场文书
2014年世界艾滋病日演讲稿
2014/11/28 职场文书
工作经历证明范本
2015/06/15 职场文书
开票证明
2015/06/23 职场文书
班主任寄语2016
2015/12/04 职场文书
微软团队与 NASA 科学家和惠普企业(HPE)的工程师合作
2022/04/21 数码科技