zoukankan      html  css  js  c++  java
  • 闭包和装饰器

    一:闭包的理解:

    闭包就是内层函数对外层函数变量的引用

    实例:

    # 闭包
    def func():
        a = 12
        def inner():
            print("a>>", a)
        return inner
    func()()

    二:装饰器的理解:

    在不改变原函数的情况下,给这个函数增加额外的功能(登陆验证和打印日志等会用到)

    简单理解版的装饰器:

    # 需求测试test的运行时间
    import time
    def test():
        a=1+34
        print("a值为〉〉",a)
    
    
    def func(f):
        def inner():
            start_time=time.time()
            time.sleep(1)
            f()
            end_time=time.time()
            print("执行时间",end_time-start_time)
        return inner
    
    test=func(test)  # inner
    test()  # inner()
    '''
    流程分析:
    第一步:执行 func(test),将test参数传入给f,这个时候,内层的inner没有执行,func()函数执行,直接返回inner,inner返回给test,
    因为test=func(test),所以,inner直接返回给左边的test,此时,test就是inner
    第二步:执行test(),其实就是执行inner(),即执行内部函数def inner().
    第三步:执行到f()时候,由于之前已经将test 参数传入到func函数里面的f,所以,现在执行f()--->test(),完成对目标函数的测试效果。
    '''

    语法糖 @ 版本装饰器

    import time
    def func(f):
        def inner():
            start_time=time.time()
            time.sleep(1)
            f()
            end_time=time.time()
            print("执行时间",end_time-start_time)
        return inner
    
    # 需求测试test的运行时间
    
    @func   # 此时,@func就相当于 test=func(test),@ 就是语法糖
    def test():
        a=1+34
        print("a值为〉〉",a)
    
    @func
    def test02():
        c="qeq"
        d="gdfa"
        print("c+d>>",c+d)
    
    # test=func(test)  # inner
    test()  # inner()
    test02()  # inner()

    三:被装饰的函数带参数的装饰器

    主要要理解,*args和**kwargs是什么

    # *args的理解,在给函数传参的时候,* 代表聚合,将传入的参数进行打包
    # 打包成一个元组
    def func01(*args):
        print("args=", args)
    
    func01(1, 2, 3)  # args= (1, 2, 3)

    **kwargs 则传入关键字参数的时候用的到

    被装饰的函数带参数:

    import time
    def func(f):
        # ** kwargs 则是在传递关键字参数的时候才用的,且必须要要用到
        def inner(*args,**kwargs):  #  此时的*args 中的 * 代表聚合,将输入的实参进行打包成一个元组
            print("1>>",args) # (10, 18)
            start_time=time.time()
            f(*args,**kwargs)  # 此时的*args 中的 * 代表打散,将传过来的元组进行打散, 比如   10 18 
            # 打成一个个的参数 10 18,然后逐一分给函数f的参数中
            print(">>",*args)  # 10 18
            end_time=time.time()
            print("执行时间",end_time-start_time)
        return inner
    
    
    # 需求测试test的运行时间
    
    @func   # 此时,@func就相当于 test=func(test),@ 就是语法糖
    def test(x,y,a):
        time.sleep(1)
        print("a值为〉〉",x+y,a) #  28  a是关键字参数
    
    @func
    def test02(x,y,z):
        time.sleep(0.2)
        print("test02的值是:",x+y+z)
    
    
    test(10,18,a="a是关键字参数")  # inner()
    # test02(1,2,1)

    被装饰的函数带返回值:

    import time
    
    
    def timer(f):
        def inner(*args, **kwargs):
            start_time = time.time()
    
            # f(*args,**kwargs)
            ret = f(*args, **kwargs)  #第二步: ret 得到的时func函数执行的返回结果,
            print(ret)
    
            end_time = time.time()
            print("执行时间〉〉", end_time - start_time)
            return ret  #  第三步: 将被装饰的函数的返回值返回给inner
    
        return inner
    
    @timer  # func=timer(func)
    def func(x, y):
        time.sleep(0.1)
        return x + y
    
    ret1 = func(1, 2)  #第一步: func(1,2)函数执行的时候,func的返回值返回给func,
    print("ret=", ret1)  # 3   第四步: 得到inner的返回值 ,其实就是被装饰的函数的返回值
  • 相关阅读:
    外文翻译 《How we decide》多巴胺的预言 第三节
    外文翻译 《How we decide》多巴胺的预言 第二节
    WPF学习12:基于MVVM Light 制作图形编辑工具(3)
    外文翻译 《How we decide》多巴胺的预言 第一节
    xcode上真机调试iphone4s出现“There was an internal API error.”解决方案
    cocos2d-x v2.2 IOS工程支持64-bit 遇坑记录
    简单优化:Zipalign
    Error: could not open `C:Javajre7libi386jvm.cfg
    【ios开发之疑难杂症】xcode运行出现SpringBoard 无法启动应用程序(错误:7)
    java IntelliJ IDEA 13 注册码 IDEA序列号 License Key
  • 原文地址:https://www.cnblogs.com/one-tom/p/11263178.html
Copyright © 2011-2022 走看看