global \ nonlocal 和 闭包

来源:互联网 发布:gx48b软件下载 编辑:程序博客网 时间:2024/06/03 11:31

一、几个概念:
1、内嵌函数:函数内部新创建另一个函数
2、闭包:函数式编程的重要语法,如果在一个内部函数里,对外部作用域(但不是在全局作用域的变量)进行引用,那么内部函数就会被认为是闭包。
3、nonlocal:用于声明局部变量。
在嵌套的函数中,如果希望在内部函数修改外部函数的局部变量,应该使用nonlocal关键字。
4、global: 如果希望在函数中修改全局变量的值,应该使用global关键字。

二、理解以下问题
1. 请问为什么代码A没有报错,但代码B却报错了?应该如何修改?

代码A:

def outside():      var = 5      def inside():          var = 3          print(var)      inside()  outside()  

代码B:

def outside():      var = 5      def inside():          print(var)          var = 3      inside()  outside()  

答:这里outside()函数里有一个var变量,但要注意的是,内嵌函数inside()也有一个同名的变量,Python为了保护变量的作用域,故将outside()的var变量屏蔽起来,因此此时是无法访问到外层的var变量的。
应该修改为:

def outside():      var = 5      def inside():          nonlocal var          print(var)          var = 8      inside()  outside()  
  1. 请问为什么代码D没有报错,但代码C却报错了?

代码C:

>>> b = 5>>> def f1(a):    print(a)    print(b)    b = 9

代码D:

>>> b = 5>>> def f2(a):    global b    print(a)    print(b)    b = 9>>> f2(3)35>>> b9

3.请问如何访问funIn()呢?

def funOut():      def funIn():          print('宾果!你成功访问到我啦!')      return funIn()  

答:funOut()
4. 请问如何访问funIn()呢?

def funOut():      def funIn():          print('宾果!你成功访问到我啦!')      return funIn  

答:funOut()()

5.以下是“闭包”的一个例子,请你目测下会打印什么内容?

>>> def funX():    x = 5    def funY():        nonlocal x        x+=1        return x    return funY>>> a = funX()>>> print(a())6>>> print(a())7>>> print(a())8

论坛的解释:
有些鱼油可能会比较疑惑,这……怎么跟全局变量一样了?局部变量x不是应该在每次调用的时候都重新初始化了吗?!

其实大家仔细看看就明白了,当a = funX()的时候,只要a变量没有被重新赋值,funX()就没有被释放,也就是说局部变量x就没有被重新初始化。

所以当全局变量不适用的时候,可以考虑使用闭包更稳定和安全,你还可以参考 -> 游戏中的角色移动:闭包在实际开发中的作用