装饰器

装饰器的作用:
不想修改函数的调用方式 但是还想在原来的函数前后添加功能
装饰器形成的过程:
最简单的装饰器 -> 有返回值的装饰器 -> 有一个参数 -> 万能参数

原则: 开饭封闭原则
开放: 对扩展是开放的
封闭: 对修改是封闭的
语法糖

最简单的装饰器
import time
def timer(f):   # 装饰器函数
    def inner():
        start = time.time()
        f()    # 被装饰的函数
        end = time.time()
        print(end-start)  # 添加的功能
    return inner

@timer      # 语法糖  @装饰器的名字
def func():     # 被装饰的函数
    time.sleep(0.05)   # 让程序在执行到这个位置的时候停0.05秒
    print('哈哈哈~~~')
# timer 就是一个装饰器函数,只是对一个函数  有一些装饰作用
# func = timer(func) 加上语法糖之后就不用写这句调用了
func()

有返回值的装饰器

def timer(f):   # 装饰器函数
    def inner():
        start = time.time()
        res = f()    # 被装饰的函数
        end = time.time()
        print(end-start)  # 添加的功能
        return res
    return inner

@timer      # 语法糖  @装饰器的名字
def func():     # 被装饰的函数
    time.sleep(0.05)   # 让程序在执行到这个位置的时候停0.05秒
    print('哈哈哈~~~')
    return 'cwc'

# func = timer(func) 加上语法糖之后就不用写这句调用了
ret = func()   # 注意
print(ret)

一个参数

def timer(f):   # 装饰器函数
    def inner(a):
        start = time.time()
        res = f(a)    # 被装饰的函数
        end = time.time()
        print(end-start)  # 添加的功能
        return res
    return inner

@timer      # 语法糖  @装饰器的名字
def func(a):     # 被装饰的函数
    time.sleep(0.05)   # 让程序在执行到这个位置的时候停0.05秒
    print('哈哈哈~~~', a)
    return 'cwc'

# func = timer(func) 加上语法糖之后就不用写这句调用了
ret = func('asca')   # 注意
print(ret)

万能参数

def timer(f):   # 装饰器函数
    def inner(*args, **kwargs):   # 接收任意的参数
        start = time.time()
        res = f(*args, **kwargs)    # 被装饰的函数
        end = time.time()
        print(end-start)  # 添加的功能
        return res
    return inner

@timer      # 语法糖  @装饰器的名字
def func(a):     # 被装饰的函数
    time.sleep(0.05)   # 让程序在执行到这个位置的时候停0.05秒
    print('哈哈哈~~~', a)
    return 'cwc'

def func(a, b):     # 被装饰的函数
    time.sleep(0.05)   # 让程序在执行到这个位置的时候停0.05秒
    print('哈哈哈~~~', a, b)
    return 'cwc'

# func = timer(func) 加上语法糖之后就不用写这句调用了
ret = func('asca', b = 4)   # 注意
print(ret)

装饰器的固定模式

def wrapper(f):   # 装饰器
    def inner(*args, **kwargs):
        '''在装饰之前要做的事'''
        ret = f(*args, **kwargs)
        '''在装饰之后要做的事'''
        return ret
    return inner

@wrapper    # 语法糖
def func(a, b):   # 被装饰的函数
    time.sleep(0.01)
    print('hahah', a, b)
    return 'lalal'

 

装饰器的进阶

带参数的装饰器

from functools import wraps
def wrapper(func):
    @wraps(func)  # 带参数的装饰器
    def inner(*args, **kwargs):
        print('在被装饰的函数执行之前做的事')
        ret = func(*args, **kwargs)
        print('在被装饰的函数执行之后做的事')
        return ret
    return inner

@wrapper
def holiday(day):
    '''放假通知'''
    print('放假%s天' % day)
    return 'happy'

print(holiday.__name__)   # 打印当前函数的名字
print(holiday.__doc__)    # 打印当前函数的注释
ret = holiday(3)   #inner
print(ret)

 

posted @ 2018-12-12 10:30  阿梵杰  阅读(115)  评论(0)    收藏  举报