浅析python装饰器
‘’’
内容:
器即函数
装饰即修饰,意指为其他函数添加新功能
装饰器定义:本质就是函数,功能是为其他函数添加新功能
装饰器=高阶函数+函数嵌套+闭包
补充:高阶函数定义:
1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名
3.满足上述条件任意一个,都可称之为高阶函数
函数嵌套定义:函数里还有函数
闭包:参数传递原则
原则:
1.不修改被装饰函数的源代码(开放封闭原则)
2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式
‘’’
怎么用:在要被装饰的函数上方加一个语法糖
打个比喻:
之前的函数功能就像是一个带有包装的一颗糖,这时候商家(程序员)想要多一个糖,但在不改变原有包装的情况下,塞不下更多的糖了。这时候的想法就是用一个更大的包装,把之前的带包装的糖和需要的新塘(功能)都放进去,新塘的和之前带包装的糖放的位置顺序依需求而定。更大的包装和新塘我们就称作装饰器。在用到装饰器的地方,肯定需要外面更大的包装做一个说明,这个说明我们叫它语法糖。
1纯净装饰器
#写好了装饰器
import time
def timer(func):
def qiantao():
start_time=time.time()
func()
stop_time=time.time()
print("函数运行花费的时间是%s"%(stop_time-start_time))
return qiantao
#第一种
# def test():
# time.sleep(1)
# print("test这个函数运行完了")
# test=timer(test)
# test()
#第二张语法糖用法(正式用法)
@timer
def test():
time.sleep(1)
print("test这个函数运行完了")
test()
2装饰器加返回值
import time
def timer(func):
def qiantao():
start_time=time.time()
res=func()
stop_time=time.time()
print("函数运行花费的时间是%s"%(stop_time-start_time))
return res
return qiantao
@timer
def test():
time.sleep(1)
print("test这个函数运行完了")
return "这样能得到test的返回值"
print(test())
3装饰器加返回值再加参数传递
import time
def timer(func):
def qiantao(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print("函数运行花费的时间是%s"%(stop_time-start_time))
return res
return qiantao
@timer
def test1(name,age,gender,*args,**kwargs):
time.sleep(1)
print(name,age,gender)
print(args)
print(kwargs)
print("test1这个函数运行完了")
return "得到test1的返回值"
@timer #tsst2=timer(test2)
def test2(jiuyige,*args,**kwargs):
time.sleep(1)
print(jiuyige)
print(args)
print(kwargs)
print("test2这个函数运行完了")
return "得到test2的返回值"
print(test1("alex",19,"male",5,rrrr=66666))
print(test2("UYYYTR","gggg",5,5,6,6,7))
4传参中args和kwargs问题
def test1(*args,**kwargs):
print(args,kwargs)
print(*args)
test2(*args,**kwargs)#这里先只看*args,**kwargs先不看。arg是一个元组(1,2,3)
#只看做是一个变量
def test2(name,age,gender):
print(name)
print(age)
print(gender)
test1(1,2,3)
#正常
def test1(*args,**kwargs):
print(args,kwargs)
print(*args)
test2(args,**kwargs)#这里先只看*args,**kwargs先不看。arg是一个元组(1,2,3)
#只看做是一个变量
def test2(name,age,gender):
print(name)
print(age)
print(gender)
test1(1,2,3)
#报错test2缺少两个参数
def test1(*args,**kwargs):
print(args,kwargs)
print(*args)
test2(args,args,args,**kwargs)#这里先只看*args,**kwargs先不看。arg是一个元组(1,2,3)
#只看做是一个变量。而*args在传参时会通过解压序列一一对应
def test2(name,age,gender):
print(name)
print(age)
print(gender)
test1(1,2,3)
#正常,打印了三个元组(1,2,3)
5终极版 带参装饰器加返回值加参数传递
import time
def timer_can(x):
def timer(func):
def qiantao(*args,**kwargs):
print(x)
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print("函数运行花费的时间是%s"%(stop_time-start_time))
return res
return qiantao
return timer
@timer_can("装饰器自带的一个参数")
#运行过程:先运行timer_can("装饰器自带的一个参数"),得到@timer,之后就都一样了
def test1(name,age,gender,*args,**kwargs):
time.sleep(1)
print(name,age,gender)
print(args)
print(kwargs)
print("test1这个函数运行完了")
return "得到test1的返回值"
@timer_can("装饰器自带的一个参数")
def test2(jiuyige,*args,**kwargs):
time.sleep(1)
print(jiuyige)
print(args)
print(kwargs)
print("test2这个函数运行完了")
return "得到test2的返回值"
print(test1("alex",19,"male",5,rrrr=66666))
print(test2("UYYYTR","gggg",5,5,6,6,7))
6个人版验证功能装饰器
user_dict={"name":None,"pwd":None}
def yanzheng(func):
def wrapper():
if user_dict["name"]=="yue"and user_dict["pwd"]=="shouhu":
func()
name = input("请输入用户名")
pwd = input("请输入密码")
if name == "yue" and pwd =="shouhu" :
user_dict["name"] = "yue"
user_dict["pwd"] = "shouhu"
func()
else:
print("输入错误")
return wrapper
@yanzheng
def home():
print("home功能已经执行")
@yanzheng
def shipping():
print("shipping功能已经执行")
home()
shipping()
7数据库版验证功能装饰器
user_list=[
{"name":"yue","pwd":"shouhu"},
{"name":"alex","pwd":"123"},
{"name":"laoyang","pwd":"234"},
{"name":"zhangshuai","pwd":"543"},
{"name":"quanhong","pwd":"765"}
]
name = 4
pwd = "5555"
def yanzheng(func):
def wrapper():
global name
global pwd
if{"name":name,"pwd":pwd}in user_list:
func()
name_shuru=input("请输入用户名").strip(" ")
pwd_shuru=input("请输入密码").strip(" ")
if {"name":name_shuru,"pwd":pwd_shuru}in user_list :
name=name_shuru
pwd=pwd_shuru
func()
else:
print("输入错误")
return wrapper
@yanzheng
def home():
print("home功能已经执行")
@yanzheng
def shipping():
print("shipping功能已经执行")
home()
shipping()
装饰器还可以装饰类,待补充
记住语法糖内容和执行先后顺序,一切皆可解