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中的装饰器。

     

  • 相关阅读:
    Zookeeper系列(二)特征及应用场景
    Scala学习笔记(三)类层级和特质
    zookeeper系列(一)安装
    Scala学习笔记(二)表达式和函数
    Spring笔记(四)SpingAOP
    Spring笔记(三)AOP前篇之动态代理
    Scala学习笔记(一)数据类型
    Linux内核系列设备模型(一) Kobject与Kset
    Spring笔记(二)Core层
    Linux内核系列之Block块层(一)
  • 原文地址:https://www.cnblogs.com/cmd61/p/11173247.html
Copyright © 2011-2022 走看看