闭包-python

闭包的概念

在 Python 中,闭包(closure)是一个常见的编程技巧。闭包是指一个函数对象,该函数能够访问其定义域外部的非全局变量,即使这些变量在函数调用时不处于活动状态也可以被访问。

def outer_func(x):
    def inner_func(y):
        return x + y
    return inner_func

closure = outer_func(10)
print(closure(5))  # 输出:15

闭包的一个常见应用场景是实现装饰器(decorator)。装饰器本质上就是一个闭包,它用于修改另一个函数的行为。

闭包不能直接修改局部变量

在 Python 中,闭包不能直接修改外部函数的局部变量是因为,在 Python 闭包的实现方式中,内部函数能够访问外部函数的变量是基于“引用”,而不是基于“值传递”的。具体来说,当一个函数被定义时,其内部函数可以访问该函数所有的局部变量,包括那些已经超出了作用域的变量,这就形成了闭包。而当内部函数引用外部函数的变量时,实际上它引用的是该变量所在的内存地址,而不是变量本身的值

因此,如果在闭包内部尝试直接修改外部函数的局部变量,则会导致该变量的内存地址发生变化,相当于创建了一个新的对象,而不是改变原有对象的值

def outer_func2():
    x = 0
    print("----outer_func2---")
    def inner_func():
        x = 1 # x的内存地址发生了变化,修改外部变量失败
        print(f"inner_func中 x={x}") # 1
    print(f"inner_func执行前 x={x}") # 0
    inner_func()
    print(f"inner_func执行后 x={x}") # 0
def outer_func3():
    x = [1,2,3]
    print("----outer_func3---")
    def inner_func():
        x[0] = 444 # x的内存地址没有发送变化,修改外部变量成功
        print(f"inner_func中 x={x}") # [444,2,3]
    print(f"inner_func执行前 x={x}") # [1,2,3]
    inner_func()
    print(f"inner_func执行后 x={x}") # [444,2,3]

闭包修改外部函数的局部变量

如果要修改外部函数的局部变量,可以使用 nonlocal关键字来通知 Python 解释器,让其知道需要修改的是外部函数的局部变量,而不是创建一个新的局部变量。
注:这种写法只适用于 Python 3,对于 Python 2.x 版本则无法直接修改外部函数的局部变量。

def outer_func4():
    x = 0
    print("----outer_func4---")
    def inner_func():
        nonlocal x
        x = 1
        print(f"inner_func中 x={x}") # 1
    print(f"inner_func执行前 x={x}") # 0
    inner_func()
    print(f"inner_func执行后 x={x}") # 1

测试代码

# 闭包的一个常见应用场景是实现装饰器
def outer_func(x):
    def inner_func(y):
        return x + y
    return inner_func
def maintest1():
    closure = outer_func(10)
    print(closure(5))  # 输出:15

# 闭包不能直接修改外部函数的局部变量
def outer_func2():
    x = 0
    print("----outer_func2---")
    def inner_func():
        x = 1
        print(f"inner_func中 x={x}")
    print(f"inner_func执行前 x={x}")
    inner_func()
    print(f"inner_func执行后 x={x}")

def outer_func3():
    x = [1,2,3]
    print("----outer_func3---")
    def inner_func():
        x[0] = 444
        print(f"inner_func中 x={x}")
    print(f"inner_func执行前 x={x}")
    inner_func()
    print(f"inner_func执行后 x={x}")

def outer_func4():
    x = 0
    print("----outer_func4---")
    def inner_func():
        nonlocal x
        x = 1
        print(f"inner_func中 x={x}")
    print(f"inner_func执行前 x={x}")
    inner_func()
    print(f"inner_func执行后 x={x}")


def maintest2():
    outer_func2()
    outer_func3()
    outer_func4()

if __name__=='__main__':
    maintest2()
    # maintest1()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值