python 高阶知识-装饰器
一、什么是装饰器?
import time def decorator(func): def wapper(): print(time.time()) func() return wapper @decorator def f1(): print("This is a function named") f1() # anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py # 1597046862.721708 # This is a function named
二、功能函数f()有入参
1、f1(funcname) ,有1个入参
import time def decorator(func): def wapper(funcname): print(time.time()) func(funcname) return wapper @decorator def f1(funcname): print("This is a function named"+funcname) f1("test") # anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py # 1597046983.011766 # This is a function namedtest
2、f1(funcname1,funcname2),有2个入参
import time def decorator(func): def wapper(funcname1,funcname2): print(time.time()) func(funcname1,funcname2) return wapper @decorator def f1(funcname1,funcname2): print("This is a function named"+funcname1) print("This is a function named"+funcname2) f1("test1","test2") # anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py # 1597047095.7641442 # This is a function namedtest1 # This is a function namedtest2
3、f1(...,...,...),有多个入参数呢?而且,decorator也不止和f1()捆绑,还会和f2(),f3()捆绑之类的,如果这些有些无参数,有些有1个,有些有2个怎么办?*args 实现
import time def decorator(func): def wapper(*args): print(time.time()) func(*args) return wapper @decorator def f1(funcname1,funcname2): print("This is a function named"+funcname1) print("This is a function named"+funcname2) f1("test1","test2") # anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py # 1597047287.727742 # This is a function namedtest1 # This is a function namedtest2
4、特殊的关键字参数怎么兼容呢?以上装饰器是不能兼容关键字参数的,比如f3的关键字参数**kw
import time def decorator(func): def wapper(*args): print(time.time()) func(*args) return wapper @decorator def f1(funcname1,funcname2): print("This is a function named"+funcname1) print("This is a function named"+funcname2) @decorator def f2(funcname1,funcname2): print("This is a function named"+funcname1) print("This is a function named"+funcname2) @decorator def f3(funcname1,funcname2,**kw): print("This is a function named"+funcname1) print("This is a function named"+funcname2) print(kw) f3("test1","test2",a=1,b=2,c='1,2,3')
#anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py
#Traceback (most recent call last):
#File "test30.py", line 22, in <module>
#f3("test1","test2",a=1,b=2,c='1,2,3')
#TypeError: wapper() got an unexpected keyword argument 'a'
怎么解决这个问题呢? 新增一个形式参数,比如用**kw(注意,形式参数是随意命名的,这里就用kw了)
import time def decorator(func): def wapper(*args,**kw): print(time.time()) func(*args,**kw) return wapper @decorator def f1(funcname1,funcname2): print("This is a function named"+funcname1) print("This is a function named"+funcname2) @decorator def f2(): print("This is a function named") print("This is a function named") @decorator def f3(funcname1,funcname2,**kw): print("This is a function named"+funcname1) print("This is a function named"+funcname2) print(kw) f3("test1","test2",a=1,b=2,c='1,2,3') f1("test1","test2") f2() # anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py # 1597047607.285459 # This is a function namedtest1 # This is a function namedtest2 # {'a': 1, 'b': 2, 'c': '1,2,3'} # 1597047607.285517 # This is a function namedtest1 # This is a function namedtest2 # 1597047607.285526 # This is a function named
三、fun()有返回值。在wrapper中保存函数计算结果,result=func(*args),然后再把返回值return 回去。
import time def display_time(func): def wrapper(*args): t1 = time.time() result = func(*args)#保存 t2 = time.time() print ("total time: {:.4} s".format(t2 - t1)) return result#返回 return wrapper def is_prime(num): if num < 2: return False if num == 2: return True for i in range(2,num): if num%i == 0: return False return True @display_time def count_num_prime(maxnum): count = 0 for i in range(2,maxnum): if is_prime(i): count = count + 1 return count count = count_num_prime(10000) print(count)
四、装饰器的应用
1、与主功能无关的逻辑,可以全部放在装饰器中执行,让主要逻辑更加明了
2、重复执行的部分,可以抽象出来,放在装饰器中,不用写太多重复代码