作用域与带有循环变量的默认参数相比较问题
2018-06-18 02:41:39来源:未知 阅读 ()
这个问题是来自于美国作家 鲁特兹(Mark Lutz)所作的一本《Learning Python,Fourth Edition》书里提及到的。
原文翻译如下:
如果 lambda 或者 def 在函数中定义,嵌套在一个循环之中,并且嵌套的函数引用了一个上层作用域的变量,该变量被循环变量所改变,所有在这个循环变量中产生的函数将会有相同的值——在最后一次循环中完成时被引用变量的值。
我们来看下一个例子:
>>> def makeActions(): ... acts = [] ... for i in range(5): ... acts.append(lambda x: i ** x) ... return acts ... >>> acts = makeActions() >>> acts[0](2) 16 >>> acts[1](2) 16 >>> acts[2](2) 16 >>> acts[3](2) 16 >>> acts[4](2) 16
批注:这个例子试图在创建一个函数的列表,其中每个函数都记住嵌套作用域中当前变量 i 的值。但是这并不怎么有效:因为嵌套作用域中的变量在嵌套的函数被调用时才进行查找,所以它们实际上记住的是同样的值(在最后一次循环迭代中循环变量的值)。
我们来看下另一个例子:
>>> def makeActions(): ... acts = [] ... for i in range(5): ... acts.append(lambda x, i = i: i ** x) ... return acts ... >>> acts = makeActions() >>> acts[0](2) 0 >>> acts[1](2) 1 >>> acts[2](2) 4 >>> acts[3](2) 9 >>> acts[4](2) 16
批注:这个是在嵌套作用域的值和默认参数方面遗留的一种仍需要解释清楚的情况,而不是引用所在的嵌套作用域的值。为了实现你想要的效果,则必须使用默认参数把当前的值传递给嵌套作用域的变量。因为默认参数是在嵌套函数所创建时评估的(而不是在其稍后调用时),每一个函数记住了自己的变量 i 的值。
你也可以将上述代码所定义的函数等价于:
>>> def makeActions(): ... acts = [] ... for i in range(5): ... def func(x): ... return i ** x ... acts.append(func(x)) ... return acts ...
与
>>> def makeActions(): ... acts = [] ... for i in range(5): ... def func(x, i = i): ... return i ** x ... acts.append(func(x, i)) ... return acts ...
批注:这是一种相当隐晦的情况,但是它会在实际情况中发生,特别是在生成应用于 GUI 一些部件的回调处理函数代码中(例如,按钮的事件处理)。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:(七)面向对象基础(一)
- Python基础之用户交互、流程控制、循环语句 2019-07-24
- Python homeWork-1 2019-07-24
- python中的for循环加强 2019-07-24
- python学习-26 函数作用域 2019-07-24
- python--006 2019-07-24
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash