zoukankan      html  css  js  c++  java
  • python-19-装饰器进阶

    前言

    假如我们写了几百个甚至更多的函数都用同一个装饰器,这时需不要使用装饰器可怎么办?一个一个取消很现实

    但是我们可以写全局的参数,让其生效或不生效。本篇将用带参数的装饰器能解决此问题:

    一、带参数的装饰器

    1、带参数装饰器,利用全局变量,flag = True or False ,  # True 就走装饰器 if ,否则不走装饰器,例一:

    import time
    flag = True         # True 就走装饰器 if ,否则不走装饰器
    
    def timmer(f):
        def inner(*args, **kwargs):
            ''' 多判断一个参数:flag,让其运行或不运行装饰函数 '''
            if flag:
                start = time.time()
                ret = f(*args, **kwargs)
                end = time.time()
                print('已等待:', end-start)
                return ret
            else:
                print('没有等待')
                ret = f(*args, **kwargs)
                return ret
        return inner
    
    @ timmer
    def gs(a):
        time.sleep(1)
        return '返回值:', a
    
    print(gs(flag))

     

     2、装饰器传参数,三层函数的装饰器,其实就在正常的装饰器再套一层,将你要传入的实参数成为装饰器内的变量参数,例二:

    import time
    flag1 = True
    def timmer_out(fg):
        def timmer(f):
            def inner(*args, **kwargs):
                if fg:
                    start = time.time()
                    ret = f(*args, **kwargs)
                    end = time.time()
                    print('已等待:', end-start)
                    return ret
                else:
                    print('没有等待')
                    ret = f(*args, **kwargs)
                    return ret
            return inner
        return timmer
    
    @ timmer_out(flag1)
    def gs1(a):
        time.sleep(1)
        return '返回值:', a
    
    print(gs1(flag1))

     

     两种效果是一样的,一个是利用全局变量,直接判断了;

    而后面这种就多嵌套一层函数在装饰器,传入参数,再用此参数判断(有点间接性)

    二、俄罗斯套娃,调用多个装饰器

    1、如下,既是调用多个装饰器:

    # 3、调用多个装饰
    # 俄罗斯套娃,上面到下面前置执行一次,然后下面到上面的后置执行一此
    def wrapper1(func):
        def inner1(*args, **kwargs):
            print('是:wrapper1--前'0)
            res = func(*args, **kwargs)
            print('是:wrapper1--后')
            return res
        return inner1
    
    def wrapper2(func):
        def inner2(*args, **kwargs):
            print('是:wrapper2--前')
            res = func(*args, **kwargs)
            print('是:wrapper2--后')
            return res
        return inner2
    
    @ wrapper1
    @ wrapper2
    def f():
        print('F')
        return '拉回给你'

    2、可以看到 f 函数上面@1、2的装饰器,这里只需要记住俄罗斯套娃一样一层一层进,一层一层出。

    运行结果如下:

     3、得出顺序:f 函数 @1、2 的装饰器,顺序为:

    ① 1 的 被装饰函数前先执行;

    ② 2 的 被装饰函数前先执行;

    ③ F 的 执行被装饰函数,不包含返回值;

    ④ 2 的 被装饰后的代码执行;

    ⑤ 1 的  被装饰后的代码执行;

    ⑥ “拉回给你”,被装饰函数的返回值;

    4、总结:你会发现就是那么简单,顺序:1→2→被装饰函数,不包含返回值→2→1→被装饰函数返回值。

    @的装饰器距离最远被装饰函数那么将先执行,简单的例子:有3个函数,装饰的顺序为:1、2、3;那么在执行时的顺序为:1、2、3、3、2、1

    是不是很像套娃呢?欢迎来QQ交流群一起学习:482713805

  • 相关阅读:
    自定义序列化类注意事项
    HashMap中的modCount
    transient
    30张图带你彻底理解红黑树(转)
    hashcode和hash算法
    线程池
    VS2015 NuGet错误:远程证书无效
    解决前台JS弹框Alert点击确定页面会刷新
    Regex中Replace方法的简单实用
    .ashx 一般处理程序
  • 原文地址:https://www.cnblogs.com/gsxl/p/12182985.html
Copyright © 2011-2022 走看看