zoukankan      html  css  js  c++  java
  • 闭包函数

    Python中的闭包

    Python中的闭包

    讲装饰器之前,先来说一下闭包。

    闭包的由来

    首先我们需要知道,我们是可以在函数中再定义一个函数的(嵌套函数)。

    就像这样:

    def foo():
        def bar():
            print("Hello world!")
        return bar
    

    此时我们调用 foo 函数,会得到一个其内部定义的 bar 函数。我们把 foo 函数的返回值赋值给一个变量就可以使用这个变量来调用 bar 函数了。

    就像这样:

    func = foo()  # func <- bar
    func()  # bar()
    

    输出:

    Hello world!
    

    好了,闭包的故事就发生在上面这样的嵌套函数中。

    举个例子:

    def foo():
        name = "Andy"  # 定义了一个foo函数内部的局部变量
        def bar():
            print(name)  # 在bar函数内部引用了其外部函数foo的局部变量name
        return bar
    
    

    现在,我们来调用一下 foo 函数:

    func = foo()
    func()
    

    上面的代码,输出结果是:

    Andy
    

    bar函数不需要传参数,就能获取到外面的变量。

    这就是典型的一个闭包现象。

    闭包的定义

    函数内部定义的函数,称为内部函数。如果这个内部函数使用了它外部函数的局部变量,即使外部函数返回了,这个内部函数还可以访问到外部函数的局部变量,这种现象就叫做闭包

    注意,即使你在调用 func 之前,定义一个全局变量 name,它还是会使用原来foo 函数内部的 name

    func = foo()
    name = "Egon"
    func()
    

    输出:

    Andy
    

    此时调用 func函数时它会使用自己定义阶段引用的外部函数的局部变量 name ,而不使用调用阶段的全局变量。

    闭包的实质

    闭包是由函数与它相关的引用环境组合而成的实体。

    Python中可以通过以下命令查看闭包相关信息:

    print(func.__closure__)
    

    输出:

    (<cell at 0x105280408: str object at 0x10544fa78>,)
    

    __closure__ 属性定义的是一个包含 cell 对象的元组,其中元组中的每一个 cell 对象用来保存作用域中变量的值。可以通过以下命令查看闭包具体包含的变量值:

    print(func.__closure__[0].cell_contents)
    

    输出:

    Andy
    

    像下面的 func函数就不能称为闭包,因为它并没有使用包含它的外部函数的局部变量。

    name = "Alex"  # 定义了一个全局变量
    def foo():
        def bar():
            print(name)  # 在bar函数内部引用了全局变量name
        return bar
    
    func = foo()
    

    此时:

    print(func.__closure__)
    

    输出:

    None
    

    闭包的介绍就到这里,接下来我们来说一说Python中的装饰器。

     

  • 相关阅读:
    左偏树
    论在Windows下远程连接Ubuntu
    ZOJ 3711 Give Me Your Hand
    SGU 495. Kids and Prizes
    POJ 2151 Check the difficulty of problems
    CodeForces 148D. Bag of mice
    HDU 3631 Shortest Path
    HDU 1869 六度分离
    HDU 2544 最短路
    HDU 3584 Cube
  • 原文地址:https://www.cnblogs.com/cmd61/p/11173247.html
Copyright © 2011-2022 走看看