深入浅析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中的type()方法的使用
May 21 Python
Python实现的堆排序算法原理与用法实例分析
Nov 22 Python
python中kmeans聚类实现代码
Feb 23 Python
python pandas写入excel文件的方法示例
Jun 25 Python
利用Python模拟登录pastebin.com的实现方法
Jul 12 Python
基于Python2、Python3中reload()的不同用法介绍
Aug 12 Python
浅析PyTorch中nn.Linear的使用
Aug 18 Python
python实现的读取网页并分词功能示例
Oct 29 Python
python numpy数组中的复制知识解析
Feb 03 Python
pymysql 插入数据 转义处理方式
Mar 02 Python
自定义Django默认的sitemap站点地图样式
Mar 04 Python
python如何调用java类
Jul 05 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.MVC的模板标签系统(四)
2006/09/05 PHP
php将时间差转换为字符串提示
2011/09/07 PHP
克隆一个新项目的快捷方式
2013/04/10 PHP
php_screw 1.5:php加密: 安装与使用详解
2013/06/20 PHP
学习php设计模式 php实现模板方法模式
2015/12/08 PHP
thinkphp框架实现路由重定义简化url访问地址的方法分析
2020/04/04 PHP
Laravel 框架基于自带的用户系统实现登录注册及错误处理功能分析
2020/04/14 PHP
基于jquery的lazy loader插件实现图片的延迟加载[简单使用]
2011/05/07 Javascript
jQuery CSS3相结合实现时钟插件
2016/01/08 Javascript
EasyUI闪屏EasyUI页面加载提示(原理+代码+效果图)
2016/02/21 Javascript
js判断radiobuttonlist的选中值显示/隐藏其它模块的实现方法
2016/08/25 Javascript
JavaScript中三种常见的排序方法
2017/02/24 Javascript
Node.js常用工具之util模块
2017/03/09 Javascript
禁止弹窗中蒙层底部页面跟随滚动的几种方法
2017/12/07 Javascript
详解element-ui中form验证杂记
2019/03/04 Javascript
React+Antd+Redux实现待办事件的方法
2019/03/14 Javascript
nodejs对项目下所有空文件夹创建gitkeep的方法
2019/08/02 NodeJs
详解Angular Karma测试的持续集成实践
2019/11/15 Javascript
Nuxt页面级缓存的实现
2020/03/09 Javascript
一篇文章带你从零快速上手Rollup
2020/09/07 Javascript
js操作两个json数组合并、去重,以及删除某一项元素
2020/09/22 Javascript
[50:29]2014 DOTA2华西杯精英邀请赛 5 24 DK VS iG
2014/05/26 DOTA
Python实现简单截取中文字符串的方法
2015/06/15 Python
python更改已存在excel文件的方法
2018/05/03 Python
Python3enumrate和range对比及示例详解
2019/07/13 Python
python爬虫解决验证码的思路及示例
2019/08/01 Python
Python Django 页面上展示固定的页码数实现代码
2019/08/21 Python
Python使用Tkinter实现转盘抽奖器的步骤详解
2020/01/06 Python
selenium设置浏览器为headless无头模式(Chrome和Firefox)
2021/01/08 Python
CSS3+Sprite实现僵尸行走动画特效源码
2016/01/27 HTML / CSS
美国受欢迎的女性牛仔裤品牌:DL1961
2016/11/12 全球购物
Nike英国官网:Nike.com (UK)
2017/02/13 全球购物
英国领先的家庭时尚品牌:Peacocks
2018/01/11 全球购物
村干部任职承诺书
2015/01/21 职场文书
公司仓管员岗位职责
2015/04/01 职场文书
幼儿园亲子活动通知
2015/04/24 职场文书