装饰器小记

1.什么是装饰器

装饰器,顾名思义在不改变原函数代码和调用方式的情况下,为函数增加一些新功能.

装饰器的本质其实就是闭包

假如现在有一个index函数如下:

import time
def index():
    time.sleep(2)
    print('欢迎登录博客园首页')

现在你要测试函数的运行时间,怎么在不改变函数源码的情况下改变呢

首先你可能会这样做:

def timmer(f):
    def inner():
        start_time = time.time()
        f()
        end_time = time.time()
        print('函数运行使用了{}时间'.format(end_time-start_time))
    return inner
index = timmer(index)
index()

在这种方法中,index函数代码没有改变,调用方式也没改变,可以测试其运行速度,但是假如index函数有返回值呢?

比如这样:

import time
def
index(): time.sleep(2) print('欢迎登录博客园首页') return 666

这样的话执行index()函数返回值为none,但是装饰器不应该改变函数返回值666

那么就应该这样做:

def timmer(f):
    def inner():
        start_time = time.time()
        r = f()

        end_time = time.time()
        print('函数运行使用了{}时间'.format(end_time-start_time))
        return r
    return inner

上面的做法比较完整但是没有考虑传参问题,标准版装饰器格式如下:

需要装饰那个函数就在函数上面加@装饰器函数名,这里是@timmer

def wrapper(f):
    '''
    添加额外的功能,执行被装饰函数之前的操作
    :param f: 被装饰函数的函数名
    :return:
    '''
    def inner(*args,**kwargs):
        '''

        :param args: 形参加*,表示聚拢位置参数
        :param kwargs: 表示聚拢关键字参数
        :return: 被装饰函数的返回值
        '''
        ret = f(*args,**kwargs)
        '''
        添加额外的功能,执行被装饰函数之后的操作
        '''
        return ret
    return inner()

完整版装饰器,例子如下:

import time
def timmer(f):
    def inner(*args,**kwargs):
        '''
        假如inner('老虎','12'),位置参数,*args把参数聚拢成元组('老虎','12')
        :param args:
        :param kwargs:
        :return:
        '''
        start_time =time.time()
        #f作为被调用的函数传入的是实参,实参里的*,**起到打散的作用

        ret = f(*args,**kwargs)
        end_time = time.time()
        print('函数执行的时间为{}'.format(end_time-start_time))
        return ret
    return inner
@timmer
def dairy(name,age):
    time.sleep(0.5)
    print('%s的年龄是%s'%(name,age))
    return 666
dairy('老王',16)

 

posted @ 2021-01-30 20:57  苦行僧冬*婷  阅读(27)  评论(0)    收藏  举报