Python的装饰器decorator

来源:互联网 发布:win10开机优化策略 编辑:程序博客网 时间:2024/06/05 00:30

Python的装饰器decorator


作者:王大为
时间:2016-10-19


一、装饰器的本质

本质:装饰器本身就是一个函数,高阶函数+嵌套函数==>装饰器
原则

    * 1、不能修改被装饰函数的源代码    * 2、不能修改被装饰函数的调用方式

二、装饰器需要的知识储备

1、函数即变量
2、高阶函数
3、嵌套函数

三、函数即变量

    形象的比喻,整个内存是一座大楼,其中每个房间存储的是对应的值,而变量名就是对应房间的门牌;一个房间的门牌可以有好几个,也就是不同的变量名可以对应同一段内存地址

这里写图片描述


对比一下四种方式的函数调用说明:变量先声明后调用
第一种
这里写图片描述
这里写图片描述


第二种
这里写图片描述
这里写图片描述


第三种
这里写图片描述
这里写图片描述


第四种
这里写图片描述
这里写图片描述


四、高阶函数

定义:满足下面条件二选一即可

* a,把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)* b,返回值中包含函数名(不修改函数的调用方式)

举例如下:
代码code结果result


五、嵌套函数

定义:函数中嵌套函数(在一个函数体内使用def定义一个局部函数)
举例如下:
这里写图片描述这里写图片描述


六、装饰器

1、基本装饰器
code代码:

import timedef timer(func):    def inner():        start_time = time.time()        func()        stop_time = time.time()        print('the func run time is %s' % (stop_time - start_time))    return inner@timerdef f1():    time.sleep(1)    print('in the f1')f1()

原理:
这里写图片描述


2、装饰的函数带有参数,需要万能参数(*args, **kwargs)

import timedef timer(func):    def inner(*args, **kwargs):        start_time = time.time()        func(*args, **kwargs)        stop_time = time.time()        print('the func run time is %s' % (stop_time - start_time))    return inner@timerdef f1(name):    time.sleep(1)    print('in the f1,%s' % name)f1('linda')

3、装饰的函数带有返回值,需要指定返回值

import timedef timer(func):    def inner():        start_time = time.time()        ret = func()        stop_time = time.time()        print('the func run time is %s' % (stop_time - start_time))        return ret    return inner@timerdef f1():    time.sleep(1)    print('in the f1')    return 'hello'print(f1())

4、单层装饰器最终版

import timedef timer(func):    def inner(*args, **kwargs):        start_time = time.time()        ret = func(*args, **kwargs)        stop_time = time.time()        print('the func run time is %s' % (stop_time - start_time))        return ret    return inner@timerdef f1(name):    time.sleep(1)    print('in the f1,%s' % name)    return 'hello'print(f1('linda'))

5、多层装饰器
代码code:

def timer1(func):    def inner1(*args, **kwargs):        print('begin in the timer1')        ret = func(*args, **kwargs)        print('stop in the timer1')        return ret    return inner1def timer2(func):    def inner2(*args, **kwargs):        print('begin in the timer2')        ret = func(*args, **kwargs)        print('stop in the timer2')        return ret    return inner2@timer1@timer2def f1(name):    print('in the f1,%s' % name)    return 'hello'f1('linda')

结果result:
这里写图片描述

原理如下:

*1、编译时:从下往上一层一层嵌套、编译*2、执行时:从上往下一层一层调用、执行

这里写图片描述


6、可以加参数的装饰器(web使用)
代码code:

def timer1(position):    print('position:', position)    def inner1(func):        def inner2(*args, **kwargs):            if position == 'local':                print('begin in the timer1')                ret = func(*args, **kwargs)                print('stop in the timer1')                return ret            else:                print('你不是本地local用户.')        return inner2    return inner1@timer1(position='now')def f1(name):    print('in the f1,%s' % name)    return 'hello'f1('linda')

6.1、当装饰器的参数为@timer1(position=’local’)
结果result:
这里写图片描述


6.2、当装饰器的参数为@timer1(position=’remote’)
结果result:
这里写图片描述

0 0