装饰器

作者: 圣堂刺客_x | 来源:发表于2019-10-22 20:17 被阅读0次

    原文链接:https://www.jianshu.com/p/95e04256264d

    装饰器本质上是一个Python函数,它可以让某个函数(对象)在不需要做任何代码变动的前提下增加额外功能。所以可以从如何增加原对象的功能角度去理解修饰器。
    定义函数func(),然后给func()增加程序耗时计算功能。

    import time
    def func():
        print("Hello")
        time.sleep(1)
        print("World")
    

    1.一般情况
    我们要想拓展原来函数代码,最直接的办法就是侵入代码里面修改,例如:

    #原始入侵,篡改原函数
    import time
    def func():
        start_time = time.time()
        print("Hello")
        time.sleep(1)
        print("World")
        end_time = time.time()
        msecs = (end_time - start_time)
        print("The elapsed time is %d ms"%msecs)
    

    2.装饰器方法
    但是如果你的Boss在公司里面和你说:“这段代码是我们公司的核心代码,你不能直接去改我们的核心代码。”那该怎么办呢,我们使用装饰器的方法试着写一下:

    #原始入侵,篡改原函数
    import time
    def deco(func):
        def wrapper():
            start_time = time.time()
            func()
            end_time = time.time()
            msecs = (end_time - start_time)*1000
            print("The elapsed time is %d ms"%msecs)
        return wrapper
    
    @deco
    def func():
        print("Hello")
        time.sleep(1)
        print("World")
    if __name__=="__main__":
        func()
    

    这里的deco函数就是最原始的装饰器,它的参数是一个函数,然后返回值也是一个函数。其中作为参数的这个函数func()就在返回函数wrapper()的内部执行。然后在函数func()前面加上@deco,func()函数就相当于被注入了计时功能,现在只要调用func(),它就已经变身为“新的功能更多”的函数了。
    所以这里装饰器就像一个注入符号:有了它,拓展了原来函数的功能既不需要侵入函数内更改代码,也不需要重复执行原函数。
    3.带参数的修饰器

    #带参数的装饰器
    import time
    def deco(func):
        def wrapper(a,b):
            if not isinstance(a,int) or not isinstance(b,int):     #校验a,b的类型是否为int类型
                return -1
            start_time = time.time()
            func(a,b)
            end_time = time.time()
            msecs = (end_time - start_time)*1000
            print("The elapsed time is %d ms"%msecs)
        return wrapper
    
    @deco
    def func(a,b):
        print("Hello,here is a func for add:")
        time.sleep(1)
        print("result is %s"%(a+b))
    if __name__=="__main__":
        func(100,200)
    

    4.带有不定参数的装饰器
    然后你满足了Boss的要求后,Boss又说:“我让你拓展的函数好多可是有参数的呀,有的参数还是个数不定的那种,你的装饰器搞的定不?

    #带不定参数的修饰器
    import time
    def deco(func):
        def wrapper(*args,**kwargs):
            print(*args)
            start_time = time.time()
            func(*args,**kwargs)
            end_time = time.time()
            msecs = (end_time - start_time)*1000
            print("The elapsed time is %d ms"%msecs)
        return wrapper
    
    @deco
    def func(a,b):
        print("Hello,here is a func for add:")
        time.sleep(1)
        print("result is %s"%(a+b))
    @deco
    def func1(a,b,c):
        print("Hello,here is a func for add:")
        time.sleep(1)
        print("result is %s"%(a+b+c))
    if __name__=="__main__":
        func(100,200)
        func1(100,200,300)
    

    5.多个装饰器
    最后,你的老板说:“可以的,我这里一个函数需要加入很多功能,一个装饰器怕是搞不定,装饰器能支持多个嘛” 最后你就把这段代码丢给了他:

    
    

    相关文章

      网友评论

          本文标题:装饰器

          本文链接:https://www.haomeiwen.com/subject/bhyiyctx.html