装饰器:
本质属性:为函数增加新功能的函数,只是有个语法糖,显得高大上而已
1 #装饰器 2 #引子 计算斐波那契数列,第50 项 3 import time 4 def fibonacci(num): 5 if num<=1: 6 return 1 7 else: 8 return fibonacci(num-1)+fibonacci(num-2) 9 start = time.time() 10 print(fibonacci(35)) 11 end = time.time() 12 print(end-start) 13 print("-----------------------------分割线1-------------") 14 ''' 15 结果:14930352 16 5.807300329208374 17 ''' 18 #计算浪费了好多的时间,比如计算9,等于7+8项,再计算第7和8 第七=5+6;第八=7+6 重复计算了第七和第6 19 #改进,增加cache 20 def fibonacci(num,cache={}): 21 22 if num<=1: 23 cache[num] = 1 24 25 return 1 26 else: 27 if num in cache.values(): 28 return cache[num] 29 result = fibonacci(num-1,cache)+fibonacci(num-2,cache) 30 cache[num] = result 31 return result 32 start = time.time() 33 print(fibonacci(35)) 34 end = time.time() 35 print(end-start) 36 ''' 37 改进结果: 38 14930352 39 6.50729775428772 40 -----------------------------分割线2------------- 41 14930352 42 0.19814443588256836 43 ''' 44 #引子2——台阶问题:一共10个台阶的楼梯,从下去上,一次迈1-3个台阶, 45 #不能后退,走完这个楼梯有多少走法 46 def climb(num,steps): 47 count = 0 48 if num==0: 49 count= 1 50 elif num>0: 51 for step in steps: 52 count += count(num-strp,steps) 53 return count 54 @memo 55 def climb_2(num,steps): 56 count = 0 57 if num==0: 58 count= 1 59 elif num>0: 60 for step in steps: 61 count += count(num-strp,steps) 62 return count 63 #此时,当num过大时,同样进行了重复的计算,比如100个台阶,当从第一个迈1个到达的50 64 #还是第一个迈2个到达的50 此后的计算都是重复的 65 ''' 66 当多个函数都用到了相同的方法来增加函数的功能时,即将函数中相同的功能抽象出来, 67 即可得到一个新的函数,这个函数用来修饰其他的函数,即这个函数就是装饰器 68 ''' 69 70 def memo(func): 71 cache ={} #每次执行内函数时,cache还会在内存中,此时是闭包 72 def wrap(*args): 73 if args not in cache: 74 cache[args] = func(*args) 75 return cache[args] 76 return wrap 77 #使用装饰器: fibonacci_2 = memo(fibonacci_2) 78 @memo 79 def fibonacci_2(num): 80 if num<=1: 81 return 1 82 else: 83 return fibonacci(num-1)+fibonacci(num-2) 84 start = time.time() 85 print(fibonacci_2(35)) 86 end = time.time() 87 print(end-start) 88 print("-----------------------------分割线3-------------")