闭包与装饰器

闭包

闭包问题 ==> 装饰器
闭包表现形式上可定义为:如果在一个内部函数里,对在外部作用域的变量进行引用,并且从外部函数将此内部函数作为返回值,那么这个内部函数就认为是闭包

装饰器

一般嵌套函数,也就是闭包才来当装饰器;
就是把装饰器下方的函数当成参数传如@之后的函数中
若执行装饰器下方的函数test()实质上就是执行@之后的函数

注意事项

在装饰器中也就是 @之后的函数传进去的参数是不加括号的,所以要自己把参数名加括号()才能传入函数,实现装饰器的功能:不破坏被装饰的源代码和调用方式,实现给@之后的函数扩展功能

# 闭包问题 ==> 装饰器
# 闭包表现形式上可定义为:如果在一个内部函数里,堆在外部作用域的变量进行引用,并且从外部函数将此内部函数
# 作为返回值,那么这个内部函数就认为是闭包closure
def fun1(a):
    print('this is fun1')
    def fun2(b=10):
        nonlocal a
        print('this is fun2')
        a=a+b
        return a
    return fun2
i=fun1(5) # 函数中有print()函数的话,把函数带着参数赋值给变量本身就调用了该函数
i()
# 输出a+b的值
print(i()) 

# 装饰器:给某程序扩展功能
"""
装饰器可在满足以下三种情况下使用
1:不能修改装饰器的函数的源代码
2:不能修改被装饰的函数的调用方式
3:满足1,2条件下给程序添加功能
"""
# 通过闭包来计算函数执行的时间
print('上面是闭包,下面是装饰器')
import time

def timer(func1):
    def deco():
        start = time.time()
        func1() # 记得加括号
        stop =time.time()
        print(stop-start)
    return deco

def test():
    time.sleep(2)
    print("测试程序!")


@timer # 一般嵌套函数,也就是闭包才来当装饰器
# 就是把装是器下方的函数当成参数传如@之后的函数中
# 若执行装饰器下方的函数test()实质上就是执行@之后的函数
# @之后的函数传进去的参数是不加括号的,所以要自己把参数名加括号()才能传入函数
def test1():
    time.sleep(2)
    print("测试程序!")

test11 = timer(test) # 以函数为参数传入函数中,可直接用函数名
test11() # 调用函数中的函数记得要加括号(嵌套函数)
print('----分隔符-----')
test1()
posted @ 2021-07-31 20:19  索匣  阅读(43)  评论(1编辑  收藏  举报