Python中装饰器的用法
- 定义:
- 装饰器本身就是一个函数
- 为其他函数提供附加功能
- 不改变源代码
- 不改变原调用方式
- 装饰器=高阶函数+嵌套函数
- 知识点:
- 函数本身就是一个变量(意味着可以被复制给一个变量:test=test(1) )
- 高阶函数
- 把函数名当成一个实参传递给另一个函数func(test1) (不改变源代码的前提下添加代码)
- 返回值中包含函数名return deco (不改变函数的调用方式)
- 嵌套函数:函数中加入新的函数def func1(): def func2():
- 典型结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 def func1(test): 2 def deco(): 3 #progress 4 return deco#返回函数的地址,达到不改变调用方式的目的
完整程序:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# __Author__Panda-J____ import time def 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)) return func @timer def test1(): time.sleep(1) print("this is test1") @timer def test2(): time.sleep(1) print("this is test2") test1() test2()
带参数的装饰器:
1 # __Author__Panda-J____ 2 3 import time 4 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 return deco 13 14 @timer 15 def test1(): 16 time.sleep(1) 17 print("this is test1") 18 19 20 21 @timer 22 def test2(arg1): 23 time.sleep(1) 24 print("this is test2,",arg1) 25 26 27 print(test1()) 28 test2("name")
本段程序的结果是
this is test1 this func running time is 1.000265121459961 None this is test2, name this func running time is 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()
我所能理解的装饰器的应用场景和关键知识点都归纳了,欢迎各位指正。