解读Python函数闭包的概念及作用域
1、在前面的内容中,我们讨论了全局变量和局部变量的作用域,也讨论了嵌套函数的作用域,并了解了局部变量或嵌套函数仅限于在函数体内使用。但在一些情况下,可以将函数内部的嵌套函数引入到全局环境中使用,Python将引入到全局环境中使用的嵌套函数及其环境变量构建成一个封闭的包,该包内的环境变量不受外部环境的影响,这就是我们将要讨论的闭包。前面我们了解了嵌套函数的作用域仅限于其父函数体内,如果在父函数体外调用其嵌套的函数,就会超出嵌套函数的作用域。

3、在Python语言中,当父函数体内定义了嵌套函数后,父函数可以把定义的嵌套函数作为希巫府浆嵌套函数的引用返回给调用者。函数的引用是什么呢?当我们定义一个函数时,不狃阝垮轹管是父函数还是父函数体内的嵌套函数。Python解释器都会为定义的函数分配内存空间,用于存储函数的代码、使用的变量等等,该内存的地址被赋值给函数名称所标识的存储单元,函数调用者可以通过函数名称所标识的存储单元找到函数的内存地址,并执行该函数。由此看来,函数名称也是一个变量,它存储了函数的内存地址。函数的内存地址既能赋值给函数名称,也可以通过函数名称赋值给其它变量,只不过其它变量存储的不是函数的直接内存地址,而是函数名称的内存地址。例如前面代码定义的line函数,可以把line函数名称的地址赋值给变量a和b,执行a、b、line的效果都是一样的。

5、上面的代码把line_conf函数内部定义的line嵌套函数返回给调用者,调用者将line嵌套函数的内存地址赋值给my_line变量,最后执行my_line所引用的line函数。执行结果如下图所示。

7、在上面的代码中,line函数使用了其父函数声明的变量b,变量b在line函数的定义易七淄苷之外,此时b为line的环境变量。当line函数作为line_conf挣窝酵聒函数的返回值时,变量b的取值已经和line函数绑定在一起,也就是说父函数和line函数绑定的变量b的值已经没有关系了,变量b即使再有变化,也不会影响到line函数的计算结果。在这种情况下,我们说line函数和它的环境变量b构成了一个闭包,闭包是一个独立的运行环境,不受外部环境的影响和约束。上面的代码输出结果为25,而不是15。下面是简单使用闭包的例子,模拟一个计数器。
