python 装饰器
理解装饰器需要作用域、闭包的知识。
函数作用域:
从小的范围开始查找。例如现在函数体内查找,然后再到全局变量查找,最后再到内置函数查找。
闭包函数示例:
1 def get_number(): 2 x = 5 # x的作用域是get_number函数内 3 def inner(): # inner是内部函数 4 print (x) 5 return (inner) #返回内部函数名 6 7 f = get_number() #第一次调用get_number时,f得到的返回值是inner。 8 f() #再次实例化f对象时和执行inner函数‘inner()’一样的。所以我们得到执行结果5.
1、最基本的装饰器函数。
1 #!/usr/bin/env python3 2 import time 3 4 def show_time(function_name): 5 def inner(): 6 start_time = time.time() 7 function_name() 8 end_time = time.time() 9 print ('run time is: {}'.format(end_time - start_time)) 10 return (inner) 11 12 @show_time # 等同于test_func = show_time(test_func) 13 def test_func(): 14 print ('test...') 15 time.sleep(1) 16 18 # 调用被装饰的函数test_func。 19 test_func()
2、给被装饰的功能函数加参数。
1 import time 2 3 def show_time(function_name): 4 def inner(*x,**y): #接收装饰器传过来的参数。 5 start_time = time.time() 6 function_name(*x,**y) #接受功能函数的参数 7 end_time = time.time() 8 print ('run time is: {}'.format(end_time - start_time)) 9 return (inner) 10 11 @show_time # 等同于test_func = show_time(test_func) 12 def test_func(*a,**b): 13 print (a) 14 print (b) 15 time.sleep(1) 16 17 # 调用被装饰的函数test_func。 18 test_func('e1','4f',str1='3',str3='test')
3、给装饰器传参数
1 import time 2 def logger(flag): 3 def show_time(function_name): 4 def inner(*x,**y): #接收装饰器传过来的参数。 5 start_time = time.time() 6 function_name(*x,**y) #接受功能函数的参数 7 end_time = time.time() 8 print ('run time is: {}'.format(end_time - start_time)) 9 print ('from logger func: {}'.format(flag)) 10 return (inner) #返回内部功能函数的内存地址 11 return (show_time) #返回装饰器函数的内存地址 12 13 @logger('logger_test') # 等同于test_func = logger(test_func) 14 def test_func(*a,**b): 15 print (a) 16 print (b) 17 time.sleep(1) 18 19 # 调用被装饰的函数test_func。 20 test_func('e1','4f',str1='3',str3='test')