作用域

定义在函数内部的变量是局部变量。局部变量不能在外部使用。示例:

  1. def fun():
  2. num = 10 # 局部变量
  3. print(num) # NameError: name 'num' is not defined

函数嵌套

在一个函数A内部再定义一个函数B,这个B就是嵌套函数。

  1. def outer():
  2. # outer 是外围函数
  3. msg = "I love you"
  4. def inner():
  5. # inner是嵌套函数
  6. print(msg)
  7. inner()
  8. print_msg() # 输出 I love you

闭包

外部函数A定义了局部变量a,内部函数B使用了a,且A的返回值为函数B。

  1. def outer():
  2. msg = "I love you"
  3. def inner():
  4. print(msg)
  5. return inner
  6. c = outer()
  7. c() # 输出 I love you

一般情况下,函数中的局部变量仅在函数的执行期间可用,闭包使得局部变量在函数外被访问了。

这里的c就是一个闭包,闭包本质是一个函数,它由inner函数和变量msg组成

闭包——修改数据

  1. x = 3
  2. def test1():
  3. x = 2
  4. def test2():
  5. print('-----A------%d' % x)
  6. x = 1
  7. print('-----B------%d' % x)
  8. return test2
  9. t = test1()
  10. t() # 报错。

程序报错,如果注释掉第8行,则输出两次2。

这是因为在第一次print时,发现函数内部有x,却没有在print语句前找到自己的x,所以报错。

类似声明全局变量一样(global),要声明nonlocal

  1. def test2():
  2. nonlocal x
  3. print('-----A------%d' % x)
  4. x = 1
  5. print('-----B------%d' % x)
  6. return test2