Python 闭包

闭包

看以下代码

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

闭包和装饰器的区别

 
  

你可能感兴趣的:(Python高阶,python,开发语言)