1.什么是闭包
如果一个函数内部定义了一个函数,我在称外面这个函数为外函数,里面的这个函数为内函数
如果内函数内部使用了外函数的临时变量,并且外函数的返回值是内函数的引用,这种形式称之为函数闭包
2.闭包的三要素
- 函数嵌套
- 外函数返回了内函数的引用
- 内函数使用外函数的临时变量
3.闭包的作用
-
闭包可以实现惰性求值
-
闭包可以保持函数的特定状态
1.惰性求值
在编程语言理论中,惰性求值目的是要最小化计算要做的工作。惰性计算的最重要的好处是它可以构造一个无限的数据类型。在延迟求值特别用于函数式编程语言中。在使用延迟求值的时候,表达式不在它被绑定到变量之后就立即求值,而是在改值被取用的时候求值意义:建立可计算的无限列表而没有妨碍计算的无限循环或大小问题。例如,可以建立生成无限斐波那契数列表的函数(经常叫做“流”)。第n个斐波那契数的计算仅是从这个无限列表上提取出这个元素,它只要求计算这个列表的前n个成员。def lazy_sum(*args): def sum(): res = 0 for i in args: res = res + i return res return sumfunc = lazy_sum(1,2,3,4,5)func()复制代码
2.状态保持
def func1() name = "python" def func(): print("I like %s" % name) return funcfunc = func1()func()如上图所示,在func函数外面在包含一层函数func1,再把func1函数的返回结果赋值给func这个变量此时func就是一个闭包函数了,把func函数加括号就可以执行了而且我们一定知道,此时func函数的执行结果一定会打印"I likepython"这句话,而且不管func函数在程序的哪个位置被调用,执行结果都是一样的复制代码
装饰器的作用
def test(func): def call_func(): print("-------") func() print("-------") return call_func @test #等同于 f1 = test(f1) def f1(): print("hhhhhh")复制代码
在不违反“开放封闭”原则的基础上,对原先的函数进行功能 扩充
- 同一个装饰器可以对多个函数进行装饰
- 每装饰一次都会产生一个闭包,被装饰的函数指向函数call_func,func形参指向了原函数
- 只要遇到@+装饰器的名称,立马进行装饰
多个装饰器对同一个函数进行装饰
- 装饰的时候装饰顺序自下向上的
- 装饰后函数的执行顺序是自上向下
通用装饰器的写法: def set_func(func): # 函数声明,*带包可以接收多个参数 def call_func(*args,**kwargs): print("---权限1-----") # * 表示拆包 ret = func(*args,**kwargs) print("----权限2----") return ret return call_func复制代码