Python Decorator装饰器[转载]
1.能墙的可以直接看视频:https://www.youtube.com/watch?v=QqRvteWBSWg
2.场景:
当一个函数中,不同逻辑混杂在一起的时候,程序的可读性会大打折扣。这个时候,可以考虑用一种叫做“装饰器”的东西来重新整理代码。这个例子简单介绍了python中装饰器的用法,遇到传参应该怎么办。
3.Code
3.1 打印10000内的质数
1 def is_prime(num): 2 if num <2: 3 return False 4 elif num ==2: 5 return True 6 else: 7 for i in range(2,num): 8 if num%i ==0: 9 return False 10 return True 11 12 def prime_nums(): 13 for i in range(2,10000): 14 if is_prime(i): 15 print i 16 17 prime_nums()
3.2 加打印前后的耗时
此函数代码中既包含了逻辑的部分,又包含了计时部分,可读性很差。
想想如果还有一堆类似的函数[也需要计时,]就需要把逻辑和计时分开,用装饰器来实现。
import time def is_prime(num): if num <2: return False elif num ==2: return True else: for i in range(2,num): if num%i ==0: return False return True def prime_nums(): t1 = time.time() for i in range(2,10000): if is_prime(i): print i t2 = time.time() print(t2-t1) prime_nums()
3.3 装饰器函数的定义和运用
@声明
@运行26行时,运行的实际是装饰器函数
输出同3.2.
1 import time 2 3 def display_time(func): 4 def wrapper(): 5 t1 = time.time() 6 func() 7 t2 = time.time() 8 print(t2 - t1) 9 return wrapper 10 11 def is_prime(num): 12 if num <2: 13 return False 14 elif num ==2: 15 return True 16 else: 17 for i in range(2,num): 18 if num%i ==0: 19 return False 20 return True 21 22 23 @display_time 24 def prime_nums(): 25 for i in range(2,10000): 26 if is_prime(i): 27 print i 28 prime_nums() #实际运行此函数,运行的是装饰器函数
至此装饰器基本介绍完毕。
3.4 扩展
加需求:统计下10000内一共有多少个质数?
#只在函数中加count 计数并没有,因为运行装饰器函数时,并未传给装饰器.

1 import time 2 3 def display_time(func): 4 def wrapper(): 5 t1 = time.time() 6 func() 7 t2 = time.time() 8 print(t2 - t1) 9 return wrapper 10 11 def is_prime(num): 12 if num <2: 13 return False 14 elif num ==2: 15 return True 16 else: 17 for i in range(2,num): 18 if num%i ==0: 19 return False 20 return True 21 22 23 @display_time 24 def count_prime_nums(): 25 count =0 26 for i in range(2,10000): 27 if is_prime(i): 28 #print i 29 count =count +1 30 return count 31 32 count = count_prime_nums 33 print count
#解决方案:
在wrapper 函数里面把返回值结果用变量result记录下来
1 import time 2 3 def display_time(func): 4 def wrapper(): 5 t1 = time.time() 6 result =func() 7 t2 = time.time() 8 #print(t2 - t1) 9 print "Total time:{:.5} s".format(t2-t1) 10 return result 11 return wrapper 12 13 def is_prime(num): 14 if num <2: 15 return False 16 elif num ==2: 17 return True 18 else: 19 for i in range(2,num): 20 if num%i ==0: 21 return False 22 return True 23 24 25 @display_time 26 def count_prime_nums(): 27 count =0 28 for i in range(2,10000): 29 if is_prime(i): 30 #print i 31 count =count +1 32 return count 33 34 count = count_prime_nums 35 print count
输出结果OK:
C:\Python27\python.exe C:/Git/Flask/me/decorator.py
Total time:0.553 s
1229
Process finished with exit code 0
3.5 扩展:如果被调用函数有参数怎么传参到装饰器?-----> 装饰器中加(*args)
如下10000->maxnum:
@display_time
def count_prime_nums(): ====》def count_prime_nums(maxnum):
汇总:
装饰器关键点:
a.首先装饰器要有一个内部定义的函数(名字不一定wrapper,可以随便起)
b.自定义函数一定要返回要调用(装饰)的函数.[如下line 10]
1 # -*- coding: UTF-8 -*- 2 #refer to https://www.youtube.com/watch?v=QqRvteWBSWg 3 import time 4 def display_time(func): 5 def wrapper(*args): # wrapper <-maxnum . *args: 可以有任意个参数 6 t1 = time.time() 7 result = func(*args) 8 t2 = time.time() 9 #print(t2 - t1) 10 print "Total time:{:.5} s".format(t2-t1) 11 return result # 必须返回被调用(装饰)函数 12 return wrapper 13 14 def is_prime(num): 15 if num <2: 16 return False 17 elif num ==2: 18 return True 19 else: 20 for i in range(2,num): 21 if num%i ==0: 22 return False 23 return True 24 25 26 @display_time 27 def count_prime_nums(maxnum): 28 count =0 29 for i in range(2,maxnum): 30 if is_prime(i): 31 #print i 32 count =count +1 33 return count 34 35 count = count_prime_nums(20000) 36 print count
输出结果:

[注]视频转载:https://www.youtube.com/watch?v=QqRvteWBSWg

浙公网安备 33010602011771号