欢迎来到Louis的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
扩大
缩小

装饰器

一. 装饰器定义

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

二. 不带参数的装饰器

from functools import wraps
import time
def wrapper(f):    
    @wraps(f)
    def inner(*args,**kwargs):            #这里参数传递用pack和unpack理解
        """在被装饰函数执行之前要做的事"""
        ret = f(*args,**kwargs) #被装饰的函数    #这里的f就是用的闭包原则,f为被装饰的函数主体
        """在被装饰函数执行之后要做的事情"""
        return ret
    return inner                    #装饰器的功能实现,实际上是在inner中,用户执行带装饰器的函数时,实际上就是在执行inner中的内容。

@wrapper        #语法糖,这里等作用于 func = wrapper(func)   返回的是inner
def func(a,b):
    time.sleep(0.01)
    print("hello,world!")
    return a+b

print(func(1,2))
def timer(f):       
    def inner():
        start_time = time.time()
        ret = f() 
        end_time = time.time()
        print(end_time-start_time)
        return ret
    return inner

@timer                  
def func():
    time.sleep(0.1)
    print("hello,world!")
    return "python"


print(func())
一个计算函数运行时间的装饰器(不带参数)

三. 带参数的装饰器

import time
from functools import wraps
def timer(flag):        #这一层就是为了把参数带进来,可让内层函数调用,这里也用的闭包思想
    def decorator(func):
        @wraps(func)
        def inner(*args,**kwargs):
            if flag:
                start_time = time.time()
                ret = func(*args, **kwargs)
                end_time = time.time()
                print(end_time-start_time)
                return ret
            else:
                return func(*args, **kwargs)
        return inner
    return decorator

flag = False

@timer(flag)        #time(flag)这里可以理解为是执行的,返回的是decorator
def foo():
    time.sleep(0.1)
    print("hello,world")

四. 总结

#装饰器的实现主要是依赖于函数能作为值传递和闭包实现的,尤其是闭包这块,函数引用闭包,装饰器参数闭包,理解这两个,装饰器就很好理解了。

 

posted on 2018-08-07 17:57  Louiszj  阅读(83)  评论(0编辑  收藏  举报

导航