Python的装饰器decorator
作者:王大为
时间:2016-10-19
一、装饰器的本质
本质:装饰器本身就是一个函数,高阶函数+嵌套函数==>装饰器
原则:
* 1、不能修改被装饰函数的源代码
* 2、不能修改被装饰函数的调用方式
二、装饰器需要的知识储备
1、函数即变量
2、高阶函数
3、嵌套函数
三、函数即变量
形象的比喻,整个内存是一座大楼,其中每个房间存储的是对应的值,而变量名就是对应房间的门牌;一个房间的门牌可以有好几个,也就是不同的变量名可以对应同一段内存地址
对比一下四种方式的函数调用说明:变量先声明后调用
第一种
第二种
第三种
第四种
四、高阶函数
定义:满足下面条件二选一即可
* a,把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
* b,返回值中包含函数名(不修改函数的调用方式)
举例如下:
五、嵌套函数
定义:函数中嵌套函数(在一个函数体内使用def定义一个局部函数)
举例如下:
六、装饰器
1、基本装饰器
code代码:
import time
def 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
@timer
def f1():
time.sleep(1)
print('in the f1')
f1()
原理:
2、装饰的函数带有参数,需要万能参数(*args, **kwargs)
import time
def 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
@timer
def f1(name):
time.sleep(1)
print('in the f1,%s' % name)
f1('linda')
3、装饰的函数带有返回值,需要指定返回值
import time
def 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
@timer
def f1():
time.sleep(1)
print('in the f1')
return 'hello'
print(f1())
4、单层装饰器最终版
import time
def 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
@timer
def 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 inner1
def 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
@timer2
def 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: