• python-装饰器


    装饰器

    简述

    如果我们想给一个类扩充功能,我们可以通过继承和组合,但是如果我们如果想给一个方法添加额外的功能呢?

    装饰器可以满足这个需求。

    装饰器是一个可调用的对象,其参数是一个函数,这个函数通常称为被装饰的函数。

    装饰器可能会处理被装饰的函数,然后返回一个函数或一个可调用对象。

    来个栗子,有一个名为decorate的装饰器

    def decorate(func):
        def inner():
            print("inner")
        return inner
    
    @decorate
    def target():
        print("target")
    
    target() #inner

    上述的代码等价于下述的代码

    def decorate(func):
        def inner():
            print("inner")
        return inner
    
    def target():
        print("target")
    
    target = decorate(target)
    target() #inner

    装饰器特性

    (1)能把被装饰的函数替换了其他的函数

    这个特性从上面的栗子就可以看出

    (2)装饰器在加载模块时立即执行

    被装饰的函数只有在调用时才执行

    def decorate(func):
        print('decorate functon:', func.__name__)
        def inner():
            print('inner')
    
        return inner
    
    @decorate
    def func1():
        print('func1')
    
    if __name__ == '__main__':
        func1()

    导入时,如果我在另一个模块导入上述代码所在的模块,结果如下:

    import decorate
    #decorate functon: func1

    运行时,如果我直接运行这个模块,结果如下:

    #decorate functon: func1
    #inner

    一般而言,装饰器通常在一个模块中定义,然后应用到其他模块中的函数上,大多数装饰器会在内部定义一个函数然后将其返回。

    装饰器的典型行为

    把被装饰的函数替换成新的函数,两者接受相同的参数,返回被装饰的函数本该返回的值,

    同时,还会做些额外操作。

    实际应用

    计时统计、记录日志,缓存运算结果等

    案例1

    编写一个记录函数运行时间的装饰器

    import time
    def log_time(func):
        def run_time(*args, **kwargs):
            begin_time = time.time()
            res = func(*args, **kwargs)
            print('spent {}s'.format(time.time() - begin_time))
         return res
    return run_time @log_time def sleep_func(): time.sleep(1) sleep_func()

    案例2

    使用类编写一个装饰器

    import time
    
    class LogTime:
    
        def __call__(self, func):
            def run_time(*args, **kwargs):
                begin_time = time.time()
                res = func(*args, **kwargs)
                print('spent {}s'.format(time.time() - begin_time))
                return res
            return run_time
    
    @LogTime()
    def sleep_func():
        time.sleep(1)
    
    sleep_func()

    案例3

    给装饰器传递参数

    class LogTime:
    
        def __init__(self, use_int):
            self.use_int = use_int
    
        def __call__(self, func):
            def run_time(*args, **kwargs):
                begin_time = time.time()
                res = func(*args, **kwargs)
                if self.use_int:
                    print('spent {}s'.format(int(time.time() - begin_time)))
                else:
                    print('spent {}s'.format(time.time() - begin_time))
                return res
            return run_time
    
    @LogTime(use_int=True)
    def sleep_func():
        time.sleep(1)
    
    sleep_func

    参考资料:《流畅的python》

  • 相关阅读:
    如何检测浏览器url变化
    nodejs学习笔记 —— 异步编程解决方案
    进程和线程总结
    angular 表达式与指令
    angular 依赖注入
    grunt 插件开发注意事项
    vmstat & mpstat & w
    css 常用布局属性解释
    前端面试题
    移动端尺寸
  • 原文地址:https://www.cnblogs.com/marton/p/10872601.html
Copyright © 2020-2023  润新知