> 文档中心 > Python高级:闭包详解

Python高级:闭包详解

闭包与装饰器

  • 知识目标
  • 知识点
    • 函数作用
    • ②闭包含义
    • ③显式查看闭包
    • ④闭包由来
    • ⑤闭包的应用

知识目标

1、理解函数的作用域;
2、掌握闭包的概念;
3、理解闭包名称的由来;
4、能够利用闭包解决实例问题。

知识点

①函数作用域

Python中函数的作用域由def关键字界定,函数内的代码访问变量的方式是从其他所有层级由内向外

def line_conf(a, b):    def line(x): return a * x + b    return line# 定义两条直线line_A = line_conf(2, 1)  # y=2x+bline_B = line_conf(3, 2)  # y=3x+2# 打印x对应y的值print(line_A(1))  # 3print(line_B(1))  # 5

嵌套函数line中的代码访问了a和b变量,line本身函数体内并不存在这两个变量,所有会逐级向外查找,往上走一层就找到了来自主函数line_conf传递a,b。若往外直至全局作用域都查找不到的话代码就会抛出异常

②闭包含义

Python支持使用嵌套函数。如果在一个内部函数中对外部函数作用域(非全局变量域)的变量进行引用,那么内部函数就会被称为闭包。
注意:闭包函数引用的外部变量不一定就是其父函数的参数,也可以是父函数作用域内的任意变量。

def line_conf():a=1b=2def line(x):print(a*x+b)return lineline=line_conf()line(3)

③显式查看闭包

_ closure _属性返回的是一个元组对象,包含了闭包引用的外部变量

def line_conf():a=1b=2def line(x):print(a*x+b)return lineline=line_conf()print(line.__closure__)for i in line.__closure__: #打印引用的外部变量值print(i.cell_contents)

Python高级:闭包详解

若主函数的闭包不引用外部变量,就不存在闭包,主函数的_closure_属性永远为None。
若主函数没有return子函数,就不存在闭包,主函数不存在_closure_属性

④闭包由来

def line_conf(a):b=1def line(x):return a*x+breturn lineline_A=line_conf(2)b=20print(line_A(1)) #3

Python高级:闭包详解

line_A对象作为line_conf返回的闭包对象,它引用了line_conf下的变量b=1,在print时,全局作用域下定义了新的b变量指向20,最终结果仍然引用的line_conf内的b。这是因为,闭包作为对象被返回时,它的引用变量就已经确定(已经保存在它的_closure_属性),不会再被修改。
闭包在被返回时,它的所有变量就已经固定,形成了一个封闭的对象,这个对象包含了其 引用的所有外部,内部变量和表达式。当然,闭包的参数例外。

⑤闭包的应用

闭包实现快速给不同项目记录日志: