• 闭包函数和装饰器


    闭包函数

    什么是闭包函数

    闭包即函数内部函数对外部作用域而非全局作用域的引用,说白了就是将函数内部的变量拿到全局来使用,还不会修改局部变量的值

    def outter():
        x = 5
        def inner():
            return x
        return inner
    
    f = outter()
    
    x = f() + 1
    print(f())
    print(x)
    
    5
    6
    

    两种为函数传参的方式

    1. 使用参数的形式
    def f1(x):
        print(x)
        
    f1(1)
    f1(2)
    f1(5)
    
    1
    2
    5
    
    1. 包给函数
    def outter(x):
        def inner():
            print(x)
        return inner
    
    f = outter(1)
    f()
    
    f1 = outter(5)
    f1()
    
    f()
    f1()
    
    1
    5
    1
    5
    

    装饰器

    无参装饰器

    什么是装饰器

    装饰器就是为函数添加额外的功能

    注意:

    • 装饰器本身其实是可以任意可调用的对象
    • 被装饰的对象也可以是任意可调用的对象

    装饰器的两大原则

    1. 不修改被装饰对象的源代码
    2. 不修改被装饰对象的调用方式

    装饰器其实就是遵循以上两大原则的前提下为被装饰对象添加功能

    怎样用装饰器

    如果我们定义一个函数,需要增加一个计时功能,我们可以使用改变源代码的方式:

    import time
    
    def index():
        start_time = time.time()
        print('睡一秒')
        time.sleep(1)
        end_time = time.time()
        print(end_time - start_time)
        
    index()
    
    睡一秒
    1.0007741451263428
    

    但这样就不符合我们装饰器的两大原则了,那我们该怎么来实现呢?

    第一种:改变调用方式

    import time
    
    def outer(func):
        
        start_time = time.time()
        res = func()
        end_time = time.time()
        print(end_time - start_time)
    
    
    def index():
        print('睡一秒')
        time.sleep(1)
        
    outer(index)
    
    睡一秒
    1.0006616115570068
    

    第二种:包给函数-外包

    import time
    
    def outer(func):
        def wrapper():
            start_time = time.time()
            res = func()
            end_time = time.time()
            print(end_time - start_time)
        return wrapper
    
    
    def index():
        print('睡一秒')
        time.sleep(1)
        
    index = outer(index)
    index()
    
    睡一秒
    1.0004618167877197
    

    完善装饰器

    上述的装饰器,最后调用index()的时候,其实是在调用wrapper(),因此如果原始的index()有返回值的时候,wrapper()函数的返回值应该和index()的返回值一样,所以我们需要同步原始的index()和wrapper()方法返回值。

    import time
    
    def outer(func):
        def wrapper():
            start_time = time.time()
            res = func()
            end_time = time.time()
            print(end_time - start_time)
            return res
        return wrapper
    
    
    def index():
        print('睡一秒')
        time.sleep(1)
        return  '我有返回值'
        
    index = outer(index)
    res = index()
    print(res)
    
    睡一秒
    1.000257968902588
    我有返回值
    

    如果原始的index()方法需要传参,那么我们之前的装饰器是无法实现该功能的,由于有wrapper()=index(),所以给wrapper()方法传参即可

    import time
    
    def outer(func):
        def wrapper(*args,**kwargs):
            start_time = time.time()
            res = func(*args,**kwargs)
            end_time = time.time()
            print(end_time - start_time)
            return res
        return wrapper
    
    
    def index(x):
        print('睡一秒')
        time.sleep(1)
        return  f"传入值为:{x}"
        
    index = outer(index)
    res = index(5)
    print(res)
    
    睡一秒
    1.0001804828643799
    传入值为:5
    

    装饰器语法糖

    import time
    
    def outer(func):
        def wrapper(*args,**kwargs):
            start_time = time.time()
            res = func(*args,**kwargs)
            end_time = time.time()
            print(end_time - start_time)
            return res
        return wrapper
    
    @outer   # index = outer(index)
    def index(x):
        print('睡一秒')
        time.sleep(1)
        return  f"传入值为:{x}"
        
    res = index(5)
    print(res)
    
    睡一秒
    1.0002069473266602
    传入值为:5
    

    装饰器模板

    def deco(func):
        def wrapper(*args,**kwargs):
            res = func(*args,**kwargs)
            return res
        return wrapper
    
    @deco
    def f1():
        pass
    
  • 相关阅读:
    利用SqlBulkCopy快速大批量导入数据
    未能完成操作,无效的FormATETC结构
    JS编码和Asp.net编码
    Sql分页两种常用算法
    Subsonic.exe 生成数据访问层代码,报“从索引 0 处开始,初始化字符串的格式不符合规范”错误解决办法
    Asp.Net,代码实现页面输出缓存
    JS中all Collection 的几个方法
    注册、反注册dll,regsvr32命令详解
    ASP.NET页面传值汇总(Session/Server.Transfer/Query String/Cookie/Application)
    表格导出EXCEL
  • 原文地址:https://www.cnblogs.com/Hades123/p/10997882.html
Copyright © 2020-2023  润新知