• 自学Python4.3-装饰器固定格式


    自学Python之路-Python基础+模块+面向对象
    自学Python之路-Python网络编程
    自学Python之路-Python并发编程+数据库+前端
    自学Python之路-django

    自学Python4.3-装饰器固定格式

    1.装饰有返回值的装饰器

    import  time
    print(time.time())
    
    def timmer(f):    #装饰器函数
        def inner():
            start = time.time()
            ret = f()       #被装饰的函数
            end = time.time()
            print(end - start)
            return ret
        return inner
    
    @timmer         #语法糖 @装饰器函数名
    def func():     #被装饰的函数
        time.sleep(0.01)
        print('我好喜欢大家啊~')
        return '新年好'
    # func = timmer(func)
    ret = func()   #inner()
    print(ret)  

    以上代码:
       执行timmer(func), 返回inner  (此时此刻func就是inner)  执行func的时候就是执行inner, 所以在inner里面加个返回值

    2. 装饰带参数函数的装饰器

    2.1 如果被装饰函数有参数, 有一个参数:

    import  time
    print(time.time())
    
    def timmer(f):    #装饰器函数
        def inner(a):
            start = time.time()
            ret = f(a)       #被装饰的函数
            end = time.time()
            print(end - start)
            return ret
        return inner
    
    @timmer         #语法糖 @装饰器函数名
    def func(a):     #被装饰的函数
        time.sleep(0.01)
        print('我好喜欢大家啊',a)
        return '新年好'
    # func = timmer(func)
    ret = func(1)   #inner()
    print(ret)
    

    2.2  如果被装饰函数有参数, 有2个参数:

    import  time
    print(time.time())
    
    def timmer(f):    #装饰器函数
        def inner(a,b):
            start = time.time()
            ret = f(a,b)       #被装饰的函数
            end = time.time()
            print(end - start)
            return ret
        return inner
    
    @timmer         #语法糖 @装饰器函数名
    def func(a,b):     #被装饰的函数
        time.sleep(0.01)
        print('我好喜欢大家啊',a,b)
        return '新年好'
    # func = timmer(func)
    ret = func(2598,2417)   #inner()
    print(ret)
    

    2.3  如果被装饰函数有2个,一个函数有1个参数, 另一个函数有2个参数:

    import  time
    print(time.time())
    
    def timmer(f):    #装饰器函数
        def inner(*args):
            start = time.time()
            ret = f(*args)       #被装饰的函数
            end = time.time()
            print(end - start)
            return ret
        return inner
    
    @timmer         #语法糖 @装饰器函数名
    def func1(a):     #被装饰的函数func1
        time.sleep(0.01)
        print('我好喜欢大家啊',a)
        return '新年好'
    # func = timmer(func)
    def func2(a,b):     #被装饰的函数func2
        time.sleep(0.01)
        print('我爱大家啊',a,b)
        return '过年好'
    # func = timmer(func)
    ret = func1(48785)   #inner()
    ret = func2(2598,2417)   #inner()
    print(ret)
    

    以上只解决了按位置传参数, 但是如果按关键字传参数就会有问题。于是,  可传万能参数

    import  time
    print(time.time())
    
    def timmer(f):    #装饰器函数
        def inner(*args,**kwargs):
            start = time.time()
            ret = f(*args,**kwargs)       #被装饰的函数
            end = time.time()
            print(end - start)
            return ret
        return inner
    
    @timmer         #语法糖 @装饰器函数名
    def func1(a):     #被装饰的函数func1
        time.sleep(0.01)
        print('我好喜欢大家啊',a)
        return '新年好'
    # func = timmer(func)
    def func2(a,b):     #被装饰的函数func2
        time.sleep(0.01)
        print('我爱大家啊',a,b)
        return '过年好'
    # func = timmer(func)
    ret = func1(48785)   #inner()
    ret = func2(2598,b=2)   #inner()
    print(ret)
    

    3. 引出---装饰器的固定格式

    def wrapper(f):    #装饰器函数,f是被装饰的函数
        def inner(*args,**kwargs):
            '''在被装饰函数之前要做的事'''
            ret = f(*args,**kwargs)    #被装饰的函数
            '''在被装饰函数之后要做的事'''
            return ret
        return inner
    @wrapper         #语法糖 @装饰器函数名
    def func(a,b):     #被装饰的函数
        time.sleep(0.01)
        print('我好喜欢大家',a,b)
        return '新年好'
    ret = func()  

    注意点:

    • func 是被装饰的函数
    • 调用所有被装饰的函数,其实就是调用的inner

     单独打印*args,会将参数打散,输出每一个参数。(接收是聚合,调用是打散)

    所以以下的例子,inner(*args) 相当于inner(1,2,3,4) 

     举例代码:

    def wrapper(func):
        def inner(*args,**kwargs):
            print('在被装饰的函数执行之前做的事')
            ret = func(*args,**kwargs)
            print('在被装饰的函数执行之后做的事')
            return ret
        return inner
    
    @wrapper   #holiday = wrapper(holiday)
    def holiday(day):
        print('全体放假%s天'%day)
        return '好开心'
    
    ret = holiday(3)
    print(ret)
    

    • 1. 执行def wrapper(func) ,放到内存
    • 2. 执行holiday=wrapper(holiday)的右部分,传给wrapper下面代码
    • 3. 执行def inner(*args,**kwargs)
    • 4. return inner 返回地址
    • 5. 返回地址给holiday , 赋值
    • 6. 执行ret=holiday(3)右部分,  就是相当于inner(3)
    • 7. 执行inner函数,print('在被装饰的函数执行之前做的事')
    • 8. ret = func(*args,**kwargs)  相当于holiday(*(3),**{})
    • 9. 执行函数holiday(3),print('全体放假%s天'%day)
    • 10. return “好开心”   
    • 11. 返回值给ret = func(*args,**kwargs) 的左部分
    • 12. print('在被装饰的函数执行之后做的事')
    • 13. return ret ,拿到返回值“好开心”
    • 14.返回值给holiday=wrapper(holiday)的左部分
    • 15.print(ret)

    ...

  • 相关阅读:
    线程池:第二章:线程池实际中使用哪一个
    实战:第五章:EZDML修改数据类型
    面试:第十四章:大厂中高级java程序员面试题
    服务网关Zuul路由转发
    启动zipkin服务
    安装Elasticsearchhead
    Zuul 路由熔断
    Unable to find local grunt.
    Kibana安装
    sleuth zipkin链路追踪
  • 原文地址:https://www.cnblogs.com/yaoyaojcy/p/10571773.html
Copyright © 2020-2023  润新知