首页 > 技术文章 > python 装饰器详解

zq8421 2018-09-04 13:25 原文

装饰器:本质就是函数,功能是为其他函数添加附加功能
原则:
1、不修改被修饰的函数的源代码
2、不修改被修饰函数的调用方式
装饰器 = 高阶函数+函数嵌套+闭包
高阶函数定义:
1、函数接收的参数是一个函数名
2、函数的返回值是一个函数名,满足任意一个,都可称为高阶函数

举个例子,现在要为一个函数添加一个额外的功能,计算这个函数的运行时间,但又不能修改原函数和调用方式,可用装饰器来实现
 1 # 装饰器的框架(函数闭包)
 2 import time
 3 def timmer(func):
 4     def wrapper():
 5         # print(func)
 6         start_time = time.time()
 7         func()  #就是在运行test()
 8         stop_time = time.time()
 9         print('函数运行时间是 %d' %(stop_time-start_time))
10     return wrapper
11 @timmer  #test = timmer(test)
12 def test():
13     time.sleep(4)
14     print('test函数运行完毕')
15 test()  
16 #--------------------------------------
17 # test = timmer(test)  #返回的是wrapper的地址
18 # test()   #执行的是wrapper()
19 # @timmer  相当于test = timmer(test)
20 #--------------------------------------
21 输出为:test函数运行完毕
22            函数运行时间是 4
23     

加上返回值

 1 # 加上返回值
  import time
2 def timmer(func): 3 def wrapper(): 4 start_time = time.time() 5 res = func() #就是在运行test() 6 stop_time = time.time() 7 print('函数运行时间是 %d' %(stop_time-start_time)) 8 return res 9 return wrapper 10 @timmer #test = timmer(test) 11 def test(): 12 time.sleep(1) 13 print('test函数运行完毕') 14 return '这是test()返回值' 15 s = test() #就是在运行wrapper 16 print(s) 17 # @timmer 相当于test = timmer(test) 18 # test = timmer(test) #返回的是wrapper的地址赋给test 19 # test() #执行的是wrapper()
输出为:
test函数运行完毕
函数运行时间是 1
这是test()返回值

再加上一些参数,修改如下

 1 import  time
 2 def timmer(func):
 3     def wrapper(*args,**kwargs):
 4         start_time = time.time()
 5         res = func(*args,**kwargs)  #就是在运行test()
 6         stop_time = time.time()
 7         print('函数运行时间是 %d' %(stop_time-start_time))
 8         return res
 9     return wrapper
10 @timmer  #test = timmer(test)
11 def test(name,age,gender):
12     time.sleep(1)
13     print('test函数运行完毕,名字是 %s,年龄是%s,性别%s' %(name,age,gender))
14     return '这是test()返回值'
15 
16 s = test('zq',20,'')    #就是在运行wrapper
17 print(s)
18 
19 输出为:test函数运行完毕,名字是 zq,年龄是20,性别男
20        函数运行时间是 1
21        这是test()返回值
22    

解压序列

 1 # 解压序列
 2 a,b,c = ('s',2,3)  #一一对应,多一个不行,少一个不行
 3 print(a)    # a
 4 s = [1,23,4,5,11,6,7,34,8,9,4,44]
 5 a,*d,c = s   #*代表中间所有的,a,c代表开头和结尾,
 6 print(c)   #44     #d代表中间所有的值的一个变量,可任取
 7 
 8 # 交换值
 9 f1 = 1
10 f2 = 2
11 print(f1,f2)    # 1 2
12 f1,f2 = f2,f1
13 print(f1,f2)    # 2 1

 


推荐阅读