定义:装饰器本身就是一个函数
为其他函数提供附加功能不改变源代码
不改变原调用方式
装饰器=高阶函数+嵌套函数
知识点:函数本身就是一个变量(意味着可以被复制给一个变量:test=test(1) )
高阶函数把函数名当成一个实参传递给另一个函数func(test1) (不改变源代码的前提下添加代码)
返回值中包含函数名return deco (不改变函数的调用方式)
嵌套函数:函数中加入新的函数deffunc1():def func2():
典型结构:
1 deffunc1(test):2 defdeco():3 #progress
4 return deco#返回函数的地址,达到不改变调用方式的目的
View Code
完整程序:
#__Author__Panda-J____
importtimedef timer(func): #for test1 & 2
start_time =time.time()
func()#run func and test its running time
end_time =time.time()print("this func running time is %s" % (end_time -start_time))returnfunc
@timerdeftest1():
time.sleep(1)print("this is test1")
@timerdeftest2():
time.sleep(1)print("this is test2")
test1()
test2()
View Code
带参数的装饰器:
1 #__Author__Panda-J____
2
3 importtime4
5
6 def timer(func): #for test1 & 2
7 def deco(*args,**kwargs):#不定参数8 start_time =time.time()9 func(*args,**kwargs) #run func and test its running time
10 end_time =time.time()11 print("this func running time is %s" % (end_time -start_time))12 returndeco13
14 @timer15 deftest1():16 time.sleep(1)17 print("this is test1")18
19
20
21 @timer22 deftest2(arg1):23 time.sleep(1)24 print("this is test2,",arg1)25
26
27 print(test1())28 test2("name")
本段程序的结果是
this istest1
this func running timeis 1.000265121459961None
thisistest2, name
this func running timeis 1.0000722408294678
问题:
1 为什么print(test1)会为None,原因是因为在装饰器中没有返回(return)任何数值给到test1中。没有可以打印的内容。
2 在28行中,test2有一个位置参数name传给了装饰器deco中,此处的arg=“name”
如果装饰器本身也带参数的情况:
需求:三层网页,分别为index,home,bbs。在登陆home和bbs页面的时候需要输入不同的用户名和密码,正确方可运行对应函数。
思路:
定义三个函数
加装饰器
用不同的用户名和密码(一个为本地Local,一个为ldap)
完整程序
# __Author__Panda-J____
#语法糖
import time
user="jiang"
pssw="123"
def auth(auth_type):#多加了一层函数进行关键字嵌套
print("auth func is",auth_type)
def outer_wrapper(func):#相当于没有装饰器参数时候的那一层
def wrapper(*args,**kwargs):#进行函数的装饰
if auth_type=="local":#使用本地用户名和密码
user_name=input("user_name:").strip()
password=input("paassword:").strip()
if user_name==user and password==pssw:#判定用户名和密码驶入正确
print("\033[32;1mUser authorized\033[0m")
return func(*args, **kwargs)#返回函数进行打印,如果没有这一行,不会执行home和bbs函数中的打印程序,home()将为None,因为没有返回任何内容
else:#用户名和密码输入不正确
exit("\033[31;1mUser failed\033[0m")
elif auth_type=="ldap":#使用ldap的密码
print("plz use ldap password")
return wrapper
return outer_wrapper
def index():
print("welcome index")
@auth(auth_type="local")#home
def home():
print("welcome home")
return "home is best"
@auth(auth_type="ldap")
def bbs():
print("welcome bss")
index()
print(home())
bbs()
我所能理解的装饰器的应用场景和关键知识点都归纳了,欢迎各位指正。