Python 闭包

Python 闭包

基本概念

概念:在 Python 中,闭包(Closure)是指在一个函数内部定义另一个函数,并且内部的函数可以引用外部函数的变量,即使外部函数已经执行完毕,这些变量的值也会被保存在闭包中。

闭包由两部分组成:

  • 外部函数:包含了一些局部变量和内部函数定义的函数。
  • 内部函数:在外部函数内部定义的函数,并且引用了外部函数的局部变量。

示例:

def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

closure = outer_function(10)

result = closure(5)  
print(result)  

在上述示例中,outer_function 是外部函数,它接受一个参数 x ,并在内部定义了一个 inner_function 函数。inner_function 函数接受一个参数 y ,并返回 x + y 的结果。

当调用 outer_function(10) 时,它返回了 inner_function 函数对象,并且 x 的值被保存在这个返回的函数对象(闭包)中。随后,将这个返回的函数对象赋值给 closure 变量。

当调用 closure(5) 时,其实是在调用 inner_function(5) ,由于闭包的特性,x 的值仍然是 10 ,所以结果为 10 + 5 = 15。

闭包的作用

1.数据隐藏与封装

通过闭包,可以将一些数据和操作封装在一个函数内部,外部无法直接访问和修改闭包内部的数据,实现了一定程度的数据隐藏和封装。

2.实现函数工厂

可以根据外部函数的参数,动态地生成具有不同行为的函数。

闭包中的变量作用域

在闭包中,外部函数的变量对于内部函数来说是处于“自由变量”(Free Variable)的状态。这些自由变量的值在闭包被创建时确定,并在闭包的生命周期内保持不变。

闭包与非局部变量

如果变量已经定义在当前作用域中,那么直接把新值交给它就行了。如果当前作用域中不存在这个变量,那么即便外围作用域里有同名的变量,Python 也还是会把这次的赋值操作当成变量的定义来处理,这会产生一个重要的效果,也就是说,Python 会把包含赋值操作的这个函数当成新定义的这个变量的作用域。

这样可以防止函数中的局部变量污染外围模块。假如不这样做,那么函数里的每条赋值语句都有可能影响全局作用域的变量,这样不仅混乱,而且会让全局变量之间彼此交互影响,从而导致很多难以探查的bug。

在闭包的内部函数中,如果要修改外部函数中的变量,需要使用 nonlocal 关键字将变量声明为非局部变量。然而,nonlocal 有个限制,就是不能侵入模块级别的作用域(以防污染全局作用域)。

def outer_function():
    count = 0
    def inner_function():
        nonlocal count
        count += 1
        return count
    return inner_function

closure = outer_function()

print(closure())
print(closure())

在上述示例中,使用 nonlocal 关键字使得在 inner_function 中可以修改 outer_function 中的 count 变量。

nonlocal 语句清楚地表明,要把数据赋给闭包之外的变量。有一种跟它互补的语句,叫作 global,用这种语句描述某个变量后,在给这个变量赋值时,系统会直接把它放到模块作用域(或者说全局作用域)中。

全局变量不应该滥用,其实 nonlocal 也这样。除比较简单的函数外,尽量不要用这个语句,因为它造成的副作用有时很难发现。尤其是在那种比较长的函数里,nonlocal 语句与其关联变量的赋值操作之间可能隔得很远。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值