栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Python Lambda闭合作用域

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python Lambda闭合作用域

原因是闭包(lambda或其他形式)关闭了名称,而不是值。定义时

lambda x: test_fun(n, x)
,不对n求值,因为它位于函数内部。调用该函数时将对其进行评估,此时该值是循环中的最后一个值。

你在一开始就说过要“使用闭包从函数签名中消除变量”,但实际上并不是这样。(不过,请参见下文,一种可能使你满意的方式,具体取决于你所说的“消除”的含义。)定义函数时,不会评估函数体内的变量。为了使函数对在函数定义时存在的变量进行“快照”,必须将变量作为参数传递。这样做的通常方法是为函数提供一个参数,其默认值为外部作用域中的变量。看一下这两个示例之间的区别:

>>> stuff = [lambda x: n+x for n in [1, 2, 3]]>>> for f in stuff:...     print f(1)444>>> stuff = [lambda x, n=n: n+x for n in [1, 2, 3]]>>> for f in stuff:...     print f(1)234

在第二个示例中,将n参数作为参数传递给“锁定”该函数的当前n值。如果要以这种方式锁定值,则必须执行类似的操作。(如果它不能以这种方式工作,那么全局变量之类的东西将根本无法工作;在使用时查找自由变量是至关重要的。)

请注意,关于此行为的所有内容都不特定于lambda。如果def用于定义引用来自封闭范围的变量的函数,则相同的作用域规则有效。

如果确实需要,可以避免在返回的函数中添加额外的参数,但是,你必须将该函数包装在另一个函数中,如下所示:

>>> def makeFunc(n):...     return lambda x: x+n>>> stuff = [makeFunc(n) for n in [1, 2, 3]]>>> for f in stuff:...     print f(1)234

在此,内部lambda仍会n在调用时查找其值。但是n它所指的不再是全局变量,而是封闭函数内部的局部变量

makeFunc
。每次
makeFunc
调用时都会创建此局部变量的新值,并且返回的lambda将创建一个闭包,该闭包“保存”对于的调用有效的局部变量值
makeFunc
。因此,循环中创建的每个函数都有其自己的“私有”变量,称为x。(对于这种简单的情况,也可以使用lambda作为外部函数—
stuff = [(lambda n: lambda x: x+n)(n) for n in [1, 2, 3]]
—来完成,但这可读性较差。)

请注意,你仍然必须将你n的参数作为参数传递,只是,通过这种方式,你不必将其作为参数传递给最终进入

stuff
列表的同一函数。而是将其作为参数传递给创建要放入的函数的辅助函数
stuff
。使用这种两种功能的方法的优点是返回的函数“干净”且没有多余的参数。如果要包装接受很多参数的函数,这可能会很有用,在这种情况下,记住
n
参数在列表中的位置可能会引起混淆。这样做的缺点是,由于需要另一个封闭函数,因此制作函数的过程更加复杂。

结果是需要权衡:你可以使函数创建过程更简单(即,不需要两个嵌套函数),但随后必须使结果函数更复杂(即,它具有这个额外的n=n参数) 。或者可以使函数更简单(即,它没有n=n参数),但是必须使函数创建过程更复杂(即,需要两个嵌套函数来实现该机制)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/441720.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号