当前位置:   article > 正文

闭包-python_python 闭包

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

闭包的一个常见应用场景是实现装饰器(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]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

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

如果要修改外部函数的局部变量,可以使用 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

测试代码

# 闭包的一个常见应用场景是实现装饰器
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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/855887
推荐阅读
相关标签
  

闽ICP备14008679号