zoukankan      html  css  js  c++  java
  • 装饰器:装饰你的梦

    装饰你的梦

    一、不用装饰器

    为函数增加计时

    def deco(func):
        start_time = time.time()
        func()
        end_time = time.time()
        print(end_time - start_time)
    
    
    def myfunc():
        time.sleep(0.6)
    
    deco(myfunc)
    
    

    二、封装一层

    def deco(func):
        def wrapper():
            start_time = time.time()
            func()
            end_time = time.time()
            print(end_time - start_time)
        return wrapper
    
    def myfunc():
        time.sleep(0.6)
    
    myfunc = deco(myfunc)
    myfunc()
    
    

    三、装饰器语法糖

    
    def deco(func):
        def wrapper():
            start_time = time.time()
            func()
            end_time = time.time()
            print(end_time - start_time)
        return wrapper
    
    @deco
    def myfunc():
        time.sleep(0.6)
    
    myfunc()
    
    
    使用了”@”语法糖后,我们就不需要额外代码来给”myfunc”重新赋值了,其实”@deco”的本质就是”myfunc=deco(myfunc)”,当认清了这一点后,后面看带参数的装饰器就简单了。
    

    四、被装饰的函数带参数

    def deco(func):
        def wrapper(a, b):
            start_time = time.time()
            func(a, b)
            end_time = time.time()
            print(end_time - start_time)
        return wrapper
    
    @deco
    def myfunc(a, b):
        print("a + b =", a+b)
        time.sleep(0.6)
    
    myfunc(10, 9)
    
    

    五、被装饰的函数带参数

    这里还有一个问题,如果多个函数拥有不同的参数形式,怎么共用同样的装饰器?在Python中,函数可以支持(*args, **kwargs)可变参数,所以装饰器可以通过可变参数形式来实现内嵌函数的签名。

    
    def deco(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            func(*args, **kwargs)
            end_time = time.time()
            print(end_time - start_time)
        return wrapper
    
    @deco
    def myfunc(a, b):
        print("a + b =", a+b)
        time.sleep(0.6)
    
    myfunc(10, 9)
    

    使用位置和关键字参数可以兼容各种函数,装饰器就成了通用的了。

    使用了*args位置参数和**kwargs关键字参数,不明白先补下知识点。

    六、被装饰函数有返回值

    def deco(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            res = func(*args, **kwargs)
            end_time = time.time()
            print(end_time - start_time)
            return res
        return wrapper
    
    @deco
    def myfunc(a, b):
        time.sleep(0.6)
        return a+b
    
    res = myfunc(10, 9)
    print(res)
    

    七、装饰器也想带参数

    功能:装饰器里的计时功能可以关闭

    def deco(arg=True):
        if arg:
            def _deco(func):
                def wrapper(*args, **kwargs):
                    start_time = time.time()
                    func(*args, **kwargs)
                    end_time = time.time()
                    print(end_time - start_time)
                return wrapper
        else:
            def _deco(func):
                return func
        return _deco
    
    @deco(arg=False)        # 这里注意下, @deco(arg=False)先执行,就变形成了@_deco(func)
    def myfunc(a, b):
        print("a + b =", a+b)
        time.sleep(0.6)
    
    myfunc(10, 9)
    
    

    又封装一层,好多层!

    八、多个装饰器

    离函数近的优先执行

    def deco_1(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            func(*args, **kwargs)
            end_time = time.time()
            print(end_time - start_time)
        return wrapper
    
    
    def deco_2(func):
        def wrapper(*args, **kwargs):
            func(*args, **kwargs)
            print("from deco_2:")
        return wrapper
    
    @deco_1
    @deco_2
    def myfunc(a, b):
        print("a + b =", a+b)
        time.sleep(0.6)
    
    myfunc(10, 9)
    
    

    参考:

    http://www.cnblogs.com/linhaifeng/articles/7532497.html#_label5
    http://python.jobbole.com/82344/
  • 相关阅读:
    AngularJS---核心特性
    前后端分离原理
    吴军 见识 读后感
    CSS 颜色名称和CSS 颜色十六进制值
    springmvc+jsp引用本地图片文件
    Eclipse 构建Maven项目--普通web项目 复制另外一个项目的配置文件导致的问题
    html input type=date 赋值问题 必须yyyy-mm-dd格式
    解决eclipse中运行web项目时弹出的"Port 8080 required by Tomcat 9.0 Server at localhost is already in use...
    解决 Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile)
    SpringMVC HelloWorld实例开发及部署
  • 原文地址:https://www.cnblogs.com/wualin/p/9795819.html
Copyright © 2011-2022 走看看