What is Decorator in Python?

首先我们要明白一点,Python和Java C++不一样 python中的函数可以像普通变量一样当作参数传递给另外一个函数 比如说下面的例子:

def foo():
    print("foo")

def bar(func):
    func()

bar(foo)

下面进入什么是装饰器范畴:
其本质上也是一个Python函数或者类,它可以让其他函数或者类在不需要做任何代码修改的前提下增加额外功能 装饰器的返回值也是一个函数或者是类的对象。他经常用于有切面需求的场景 比如说插入日志 性能测试,事务处理,缓存 权限。装饰器是解决这些问题的绝佳设计。因为有了装饰器的存在 我们可以抽离出大量的与函数功能本身无关的雷同代码到装饰起中并继续重用。

简单示例:
如果我们需要对多个函数进行运行时间的统计,如果不会装饰器,那么我们会写成这样:

from time import time, sleep
​
def fun_one():
    start = time()
    sleep(1)
    end = time()
    cost_time = end - start
    print("func one run time {}".format(cost_time))
    
def fun_two():
    start = time()
    sleep(1)
    end = time()
    cost_time = end - start
    print("func two run time {}".format(cost_time))
    
def fun_three():
    start = time()
    sleep(1)
    end = time()
    cost_time = end - start
    print("func three run time {}".format(cost_time))

如果会装饰器的话 就是下面这样:

def run_time(func):
    def wrapper():
        start = time()
        func()                  # 函数在这里运行
        end = time()
        cost_time = end - start
        print("func three run time {}".format(cost_time))
    return wrapper
​
@run_time
def fun_one():
    sleep(1)
    
@run_time
def fun_two():
    sleep(1)
    
@run_time
def fun_three():
    sleep(1)

当然 上面只是简单的装饰器,下面我们来看一下带参数的装饰器
之前的日志打印器 信息太过单薄,需要他携带更多的信息,比如函数名称和日志等级。这时候可以把函数名称和日志等级作为装饰器的参数,具体见下面代码:

def logger(msg=None):
    def run_time(func):
        def wrapper(*args, **kwargs):
            start = time()
            func()                  # 函数在这里运行
            end = time()
            cost_time = end - start
            print("[{}] func three run time {}".format(msg, cost_time))
        return wrapper
    return run_time
​
@logger(msg="One")
def fun_one():
    sleep(1)
    
@logger(msg="Two")
def fun_two():
    sleep(1)
    
@logger(msg="Three")
def fun_three():
    sleep(1)
    
fun_one()
fun_two()
fun_three()

references:
https://foofish.net/python-decorator.html#:~:text=%E8%A3%85%E9%A5%B0%E5%99%A8%E6%9C%AC%E8%B4%A8%E4%B8%8A%E6%98%AF,%E4%B9%9F%E6%98%AF%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%2F%E7%B1%BB%E5%AF%B9%E8%B1%A1%E3%80%82&text=%E6%9C%89%E4%BA%86%E8%A3%85%E9%A5%B0%E5%99%A8%EF%BC%8C%E6%88%91%E4%BB%AC,%E5%AF%B9%E8%B1%A1%E6%B7%BB%E5%8A%A0%E9%A2%9D%E5%A4%96%E7%9A%84%E5%8A%9F%E8%83%BD%E3%80%82
https://www.zhihu.com/question/325817179

posted @ 2020-10-18 04:58  EvanMeetTheWorld  阅读(27)  评论(0)    收藏  举报