看以下代码
func_list = []
for i in range(3):
def myfunc(a):
return i + a
func_list.append(myfunc)
for f in func_list:
print(f(1)) # 打印出三个 3
# 由返回结果可知,i 的值为 2,因为 i 是外部变量,会随着外部的 range 函数而改变
# 当调用 func_list 中的函数时,i 的值已经变为了 2
# 相当于以下代码:
for i in range(3):
pass
# 运行到这 i = 2
def myfunc(a):
return i + a
# 然后运行 myfunc(1),返回 3
如果想让 i 的值保持为 0 1 2 ,可以使用闭包
func_list = []
for i in range(3):
def func(num): # 此处的 num 可以随意命名,也可以命名为 i
# 原理:
# 在 func 函数内部定义了一个局部变量 num
# num 接收参数:num = i
# 此处的 num 只是一个局部变量,与其他无关
# 相当于 func 函数内部一开始就有一个变量定义,其值为 i 的值:num = i
# 第一次调用 func 函数,开辟了一个新的空间,有 num = 0,def myfunc() 定义
# 第二次调用 func 函数,开辟了一个新的空间,有 num = 1,def myfunc() 定义
# 第三次调用 func 函数,开辟了一个新的空间,有 num = 2,def myfunc() 定义
# 无论什么时候执行 myfunc 函数,不同的 num 都存在
def myfunc(a):
return num + a # 此处的 num 保存了外部的 i,分别为 0 1 2
return myfunc
# 借 func 函数把 i 的值传给函数内部的局部变量 num
# func(i) 返回 myfunc
# 等价于 func_list.append(myfunc)
func_list.append(func(i))
for f in func_list:
print(f(1)) # 打印出 1 2 3
可以用来在一个函数与一组私有变量之间创建关联关系,在给定函数被多次调用的过程中,这些私有变量能够保持其持久性(保存运行环境与变量的状态)
def power(exp): # exp 表示指数
def exp_of(base): # base 基数
return base ** exp
return exp_of
square = power(2) # 得到一个求任意数平方的函数
cube = power(3) # 得到一个求任意数立方的函数
print(square(2))
print(square(3))
print(cube(2))
print(cube(3))
def outer():
x = 0
y = 0
def inner(x1, y1):
nonlocal x, y
x += x1
y += y1
print(f"当前 x = {x},y = {y}")
return inner
move = outer()
move(1, 1) # 当前 x = 1,y = 1
# 从结果看出现在的值是加上了上一次的 2+1=3 1+5=6
# 实现了记忆功能
move(2, 5) # 当前 x = 3,y = 6