zoukankan      html  css  js  c++  java
  • 十二天:闭包和装饰器

    闭包函数

    什么是闭包函数

    在一个内嵌函数中,对在外部的函数变量的引用,那么着个内嵌函数就被成为闭包函数

    定义在外部函数但由内部函数引用的变量被称为自由变量

    闭包函数至少是个函数嵌套

    def f1(x):
        def f2():
            print(x)
        return f2
    num = f1(2)
    num()
    
    def outer(x,y):
        def inner():
             nonlocal x ,y
             x += 1
             y += 2
             print(f'x:{x},y:{y}')
        return inner
    test = outer(2,5)
    test()
    test()
    

    使用闭包函数去掉了全局变量的使用,而且将inner函数封装在了outer函数中,使外部不可调用。

    当函数outer运行完成后,它的参数x,y依然存在,因为他们被闭包了,所以不会被回收。

    装饰器

    装饰器相当于闭包函数的高级应用,闭包函数传的参数是变量,而装饰器传的参数是一个函数。装饰器是用来不修改源码和调用方式来给原函数增加功能的。

    1. 装饰器本身是函数,只不过它用来装饰 被装饰的函数
    2. 装饰器装饰函数 不改变被装饰函数源代码
    3. 装饰器装饰函数 不改变被装饰函数的调用方式
    import time
    
    
    def index():
        """被装饰的函数"""
        print('index')
        time.sleep(1)
    
    
    # time_count装饰器:对被装饰函数计时
    def time_count(func):  # func才是真正的index
        """装饰器"""
    
        def wrapper():
            start = time.time()
            func()
            end = time.time()
            print(end - start)
    
        return wrapper
    
    
    index = time_count(index)  # index == wrapper
    index()  # wrapper()
    
    

    带返回值的装饰器

    import time
    
    
    def index():
        """被装饰的函数"""
        print('x',x)
        print('index')
        time.sleep(1)
    
        return 'index'
    
    
    # time_count装饰器:对被装饰函数计时
    def time_count(func):  # func才是真正的index
        """装饰器"""
        def wrapper():
            start = time.time()
            res = func()  # index()
            end = time.time()
            print(end - start)
            return res
    
        return wrapper
    
    
    index = time_count(index)  # index == wrapper
    res = index()  # wrapper()
    print(res)
    

    对于有返回值的函数,我们可以拿一个变量名去接收这个返回值

    res = func() 然后return res

    有参数的装饰器

    import time
    
    
    def index(x,y,z=10):
        """被装饰的函数"""
        print('x',x)
        print('index')
        time.sleep(1)
    
        return 'index'
    
    
    # time_count装饰器:对被装饰函数计时
    def time_count(func):  # func才是真正的index
        """装饰器"""
    
        def wrapper(*args,**kwargs):  # (10, 20)  # *args和**kwargs接收了所有的参数
            start = time.time()
            res = func(*args,**kwargs)  # index()  # *(10,20)  # *args和**kwargs打散参数传给真正的index
            end = time.time()
            print(end - start)
    
            return res
    
        return wrapper
    
    
    index = time_count(index)  # index == wrapper
    res = index(10,20,320)  # wrapper()
    print(res)
    
    

    假如我们不知道原函数有多少参数,我们就可以在装饰器中使用可变长参数

    def wrapper(*args,**kwargs):

    res = func(*args,**kwargs)

    最后使用时再传值进去

    装饰器语法糖

    @装饰器的函数名

    index = time_count(index) == @time_count

    装饰器函数要写在被装饰函数的上面,@下面写被装饰函数。

    装饰器模板

    综上,我们就可以得到一个装饰器的模板,使用时直接套用就好了

    def deco(func):
        def wrapper(*args,**kwargs):
            res = func(*args,**kwargs)
            pass
            return res
        return wrapper
    
        @decp
        def show(name, age):
            print(name,age)
    
        show('ly',10)
    
    
  • 相关阅读:
    网页鼠标点击特效
    ElementUI 删除 el-table 当前选中行(不是selection列)
    Vue阻止冒泡
    Vue实现选项卡切换
    Vue的条件渲染
    Vue实现勾选后向数组都添加
    Vue实现商城里面多个商品计算,全选,删除
    VUE实现请求数据
    JS实现数组每次只显示5条数据
    移动端分享到微信和QQ
  • 原文地址:https://www.cnblogs.com/lyyblog0715/p/11574951.html
Copyright © 2011-2022 走看看