python 3层装饰器及应用场景

发布时间:2019-09-24 08:18:13编辑:auto阅读(1331)

    #!/usr/bin/env python

    # -*- coding:utf-8 -*-

    # author: Changhua Gong

    import time, functools


    '''

    实现装饰器:

    1.函数即变量;

    2.高阶函数;

        1)把一个函数名当做实参传给另一个函数(在不修改被装饰函数的源代码情况下为其添加功能);

        2)返回值中,包含函数名(不修改函数的调用方试)。

    3.嵌套函数(在一个函数中,用def去声明另一个函数)。

    原则:

    1.不能修改被装饰的函数的源代码;

    2.不能修改被装饰的函数的调用方试。

    补:

    1.函数在调用前,只要其涉及到的变量均在调用前别解释完全(无论先后顺序)

      即可顺利执行。


    '''



    def timmer(func):

        # @functools.wraps(func)  #加上这个装饰后test的函数名就不是wrapper了,而是test,注意位置(http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318435599930270c0381a3b44db991cd6d858064ac0000)

        def wrapper(*args, **kv):

            time_b = time.time()

            return (func(*args, **kv))

            time_e = time.time()

            print("Function %s runned for %ss" % (func.__name__, (time_e - time_b)))


        return wrapper  # 注意这个return的位置



    # 写在装饰的函数的前面,装饰多个函数,每个函数前面需加上@decorator

    @timmer  # test = timmer(test) = wrapper, 调用时test() = wrapper(),这里说明参数的传输问题

    # test(*args,**kv) = wrapper(*args,**kv)

    def test():

        print("Function test begins running.")

        time.sleep(0.2)

        print("Function test ends running.")

        return "测试"


    print("通过2层装饰器函数名更替为:%s" % test.__name__)

    print(test())

    print("-----------------------------------------")



    def timmer(func):

        #@functools.wraps(func)

        def wrapper(*args, **kv):

            time_b = time.time()

            print("Begin calling.")

            rs = func(*args, **kv)  # 将函数返回值赋给rs

            print("End calling.")

            return rs  # 这里返回函数执行完后的返回值

            time_e = time.time()

            print("Function %s runned for %ss" % (func.__name__, (time_e - time_b)))


        return wrapper  # 注意这个return的位置



    # 写在装饰的函数的前面,装饰多个函数,每个函数前面需加上@decorator

    @timmer  # test = timmer(test) = wrapper, 调用时test() = wrapper(),这里说明参数的传输问题

    # test(*args,**kv) = wrapper(*args,**kv)

    def test():

        print("Function test begins running.")

        time.sleep(0.2)

        print("Function test ends running.")

        return "测试"


    print("通过2层装饰器函数名更替为:%s" % test.__name__)

    print(test())

    print("-----------------------------------------")

    '''

    上述装饰器都是简单的两层。

    如果装饰器本身需要传入参数,则需要3层(应用场景如:登录网页使用微信、QQ、还是邮箱)。

    '''



    def login(login_type):

        def timmer(func):

            #@functools.wraps(func)

            def wrapper(*args, **kv):

                time_b = time.time()

                if login_type == "QQ":

                    print("Login by QQ.")

                    return (func(*args, **kv))

                else:

                    print("Login by Others.")

                    return (func(*args, **kv))

                time_e = time.time()

                print("Function %s runned for %ss" % (func.__name__, (time_e - time_b)))

            return wrapper  # 注意这个return的位置

        return timmer # 注意这个return的位置


    # 写在装饰的函数的前面,装饰多个函数,每个函数前面需加上@decorator

    @login("QQ")  # test = timmer(test) = wrapper, 调用时test() = wrapper(),这里说明参数的传输问题

    # test(*args,**kv) = wrapper(*args,**kv)

    def test():

        print("Function test begins running.")

        time.sleep(0.2)

        print("Function test ends running.")

        return "测试"



    print("通过3层装饰器函数名更替为:%s" % test.__name__)

    print(test())


关键字