函数注解与匿名函数
关于函数参数的定义,调用以及函数参数的内容,在下面的文章中已经做了初步的介绍,有需要的可以访问进行了解:
Python 函数
函数注解
在编写函数,当下肯定清楚函数如何使用的。若是函数较为复杂,过段时间,编写者有可能需要花一段时间去重新了解函数的使用,那其他使用者也同样会遇到这样的困惑。
所以当编写完函数后,可以为函数的参数添加一些额外的信息。这里给函数参数添加注解,能够提示程序员如何正确使用这个函数。如下示例:
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.
总结
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 【雨果唱片】中国管弦乐《鹿回头》WAV
- APM亚流新世代《一起冒险》[FLAC/分轨][106.77MB]
- 崔健《飞狗》律冻文化[WAV+CUE][1.1G]
- 罗志祥《舞状元 (Explicit)》[320K/MP3][66.77MB]
- 尤雅.1997-幽雅精粹2CD【南方】【WAV+CUE】
- 张惠妹.2007-STAR(引进版)【EMI百代】【WAV+CUE】
- 群星.2008-LOVE情歌集VOL.8【正东】【WAV+CUE】
- 罗志祥《舞状元 (Explicit)》[FLAC/分轨][360.76MB]
- Tank《我不伟大,至少我能改变我。》[320K/MP3][160.41MB]
- Tank《我不伟大,至少我能改变我。》[FLAC/分轨][236.89MB]
- CD圣经推荐-夏韶声《谙2》SACD-ISO
- 钟镇涛-《百分百钟镇涛》首批限量版SACD-ISO
- 群星《继续微笑致敬许冠杰》[低速原抓WAV+CUE]
- 潘秀琼.2003-国语难忘金曲珍藏集【皇星全音】【WAV+CUE】
- 林东松.1997-2039玫瑰事件【宝丽金】【WAV+CUE】