1.装饰器定义和原则
定义:装饰器本质是一个函数,(装饰其它函数)就是为其它函数添加附加功能。
原则:不能修改被装饰函数的源代码;不能修改被装饰函数的调用方式。
2.实现装饰器知识储备
1.函数即变量
2.高阶函数
a.把一个函数名当做实参传给另一个函数--》可以实现不修改被装饰函数的源代码,为其它函数添加附加功能
import time
def test1():
time.sleep(3)
print("this is test1")
def test2(func):
start_time = time.time()
func()
stop_time = time.time()
print("this func run time is %s"%(stop_time-start_time))
test2(test1)
b.返回值中包含函数名-->可以实现不修改被装饰函数的调用方式
def test3():
print("this is test3")
def test4(func):
print("附加功能")
return func
test3 = test4(test3)
test3()
注:调用函数的时候不加括号表示调用该函数内存地址如:print(test3)--><function test3 at 0x003E7660>,加括号表示执行该函数
3.嵌套函数 ,在一个函数里再次声明一个函数
def test5():
print("this is test5")
def test6(): #类似于局部变量,只能在局部调用
print("this is test6")
test6()
test5()
4.高阶函数+嵌套函数--》装饰器
a.装饰器举例1
import time
#装饰器:增加计算函数运行时间的功能
def timer(func):
def deco(*args,**kwargs): #在装饰器中增加*args,**kwargs之后,无论原函数参数的个数是多少,都可以适应
start_time = time.time()
res = func(*args,**kwargs)
stop_time = time.time()
print("this func run time is %s"%(stop_time-start_time))
return res #在装饰器中增加return res之后,可以返回原函数中的返回值
return deco
#下面的1,2也就是装饰器执行的过程
#原函数
@timer #1、 @timer 实际上是在执行“test1 = timer(test1)”-->将原test1 内存地址传给func,然后直接将deco的内存地址返回到test1
def test1():
time.sleep(3)
print("this is test1")
#test1 = timer(test1)
test1() #2、这时test1()相当于直接调用deco(*args,**kwargs),而deco里的func还是指向的原test1的内存地址
@timer
def test2(name):
time.sleep(1)
print("this is %s"%(name))
test2("fengxiaoli")
@timer
def test3(name):
time.sleep(2)
print("this is %s"%(name))
return "test3 res"
print(test3("cx")) #先执行test3(cx),再打印test3的返回结果
b.装饰器举例2
#给网页增加一个验证的功能,并且home页面用本地验证,bbs页面用ldap验证
user = "fengxiaoli"
passwd = "123456"
def auth(auth_type):
def out_wrapper(func):
def wrapper(*args,**kwargs):
if auth_type == "local":
user_name = input("请输入用户名:").strip()
password = input("请输入密码:").strip()
if user_name == user and password == passwd:
res = func(*args,**kwargs)
print("welcome to home!")
return res
else:
print("用户名或密码错误")
else:
print("ldap login")
return wrapper
return out_wrapper
#原函数
def index():
print("this is index")
@auth(auth_type="local") #相对于装饰器1中的例子,这里调用装饰器的时候使用了参数,在1中装饰器不变得情况下直接在外在嵌套了一层函数,最外层函数接收的就是装饰器中的参数
def home():
print("this is home page")
home()
@auth(auth_type="ldap")
def bbs():
print("this is bbs page")
bbs()
转载于:https://blog.51cto.com/fengxiaoli/2177518