包含python闭包函数优势的词条( 二 )


形成闭包之后,闭包函数会获得一个非空的_Closure_属性,这个属性是一个元组 。
组里面的对象为cell对象,而访问cell对象的cell_contents属性则可以得到闭包变量的当前值 。
而随着闭包的继续调用,变量会进行再次更新 。由此可见,一般形成闭包之后,Python确定会将_closure_和闭包函数绑定作为储存闭包变量的场所 。
闭包的好处是什么?
其实,闭包并不是必须的 。
没有闭包的话,Python的功能不会受到任何影响;但有了闭包之后,可以提供一种额外的解决方案 。
闭包是什么 , 有什么特性,对页面有什么影响闭包是可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量) 。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域) 。在 Scala、Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby、 Python、Go、Lua、objective c、swift 以及Java(Java8及以上)等语言中都能找到对闭包不同程度的支持 。
闭包 (closure)是个精确但又很难解释的电脑名词 。在 Perl 里面 , 闭包是以 匿名函数的形式来实现,具有持续参照位于该函数范围之外的文字式变数值的能力 。这些外部的文字变数会神奇地保留它们在闭包函数最初定义时的值 (深连结) 。
如果一个程式语言容许函数递回另一个函数的话 (像 Perl 就是) , 闭包便具有意义 。要注意的是,有些语言虽提供匿名函数的功能 , 但却无法正确处理闭包; Python 这个语言便是一例 。如果要想多了解闭包的话,建议你去找本功能性程式 设计的教科书来看 。Scheme这个语言不仅支持闭包,更鼓励多加使用 。
以下是个典型的产生函数的函数:
sub add_function_generator {
return sub { shift + shift };
}
$add_sub = add_function_generator();
$sum = $add_sub(4,5); # $sum是 9了
闭包用起来就像是个函数样板,其中保留了一些可以在稍後再填入的空格 。add_function_generator() 所递回的匿名函数在技术上来讲并不能算是一个闭包 ,  因为它没有用到任何位在这个函数范围之外的文字变数 。
把上面这个例子和下面这个make_adder()函数对照一下,下面这个函数所递回的匿名函数中使用了一个外部的文字变数 。这种指明外部函数的作法需要由 Perl递回一个适当的闭包 , 因此那个文字变数在匿名函数产生之时的值便永久地被锁进闭包里 。
sub make_adder {
my $addpiece = shift;
return sub { shift + $addpiece };
}
$f1 = make_adder(20);
$f2 = make_adder(555);
这样一来$f1($n) 永远会是 20加上你传进去的值$n,而$f2($n) 将 永远会是 555加上你传进去的值$n 。$addpiece的值会在闭包中保留下来 。
闭包在比较实际的场合中也常用得到,譬如当你想把一些程式码传入一个函数时:
my $line;
timeout(30,sub { $line = STDIN });
如果要执行的程式码当初是以字串的形式传入的话,即'$line = STDIN',那么timeout() 这个假想的函数在回到该函数被呼叫时所在的范围後便无法再撷取$line这个文字变数的值了 。
语法结构编辑
Groovy的闭包
闭包(Closure)是Java所不具备的语法结构 。闭包就是一个代码块,用“{ }”包起来 。此时 , 程序代码也就成了数据,可以被一个变量所引用(与C语言的函数指针比较类似) 。闭包的最典型的应用是实现回调函数(callback) 。Groovy的API大量使用闭包,以实现对外开放 。闭包的创建过程很简单 , 例如: