##开场白
什么是装饰器?
装饰器:
定义:本质是函数,是用来装饰其他函数,就是为其他函数添加附加功能
原则:1.不能修改被装饰函数的源代码
2.不能修改被装饰的调用方式
装饰器有什么用?
如果这写函数正在运行中,现在又需要修改程序,问怎么做?
这就是用装饰器的用处
##你需要具备的知识
函数即变量
高阶函数
1.把一个函数名当做实参传给另外一个函数
2.返回值中包含函数名
嵌套函数
嵌套函数+高阶函数 --> 装饰器
###先来看一个栗子
import time
def test1():
time.sleep(3)
print('in the test1')
def test2():
time.sleep(3)
print('in the test2')
#如果要装饰test1或test2,就要做下面的操作
def timer(func): #其实就是返回一个返回一个内存地址,返回的是test3的地址
def test3():
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
return test3 #这里是将test3的内存地址赋给test1,然后执行的是test3
#在这里你执行test1实际上是执行了test3,但是发现,我并没有修改test1
#的调用方式,但是输出结果却是真正的对test1原有的功能做了添加和优化
test1 = timer(test1) #因此这里实际上执行的是test3,但是在这里面它执行了test1而已
test1()
####到这里其实就是装饰器的雏形了,不要急,继续来!
##装饰器小高潮
import time
def timer(func): #其实就是返回一个返回一个内存地址,返回的是test3的地址
def test3(*args,**kwargs): #这里传入非固定参数,表示可有可无,可单个,可多个
start_time = time.time()
x = func(*args,**kwargs) #这里表示是被装饰的函数传递的参数
end_time = time.time()
print(end_time - start_time)
# print('x表示被装饰函数的返回值:',x)
return 'x表示被装饰函数的返回值:%s'%x
return test3 #这里是将test3的内存地址赋给test1,然后执行的是test3
#因此这里实际上执行的是test3,但是在这里面它执行了test1而已
# 最终实现的效果
@timer # 相当于test1 = timer(test1)
def test1(): #这里没有传入参数,因此在装饰器中使用了非固定参数解决
time.sleep(2)
x = 1
print('in the test1')
return x
@timer
def test2(name,age): #这里传入了两个参数
time.sleep(1)
print('in the test2 :',name,age)
# 这就是装饰器,没有修改运行test1函数,只是自己写了一个函数然后使用装饰器装饰后使用
print(test1())
# test2(1,2)
###最终高潮版
import time
user,pawd = 'asd','123' #模拟本地的用户名、密码
def auth(auth_type):
# print('auth func:',auth_type)
def outer_wrapper(func):
def wrapper(*args, **kwargs):
print('wrapper func args kwargs:',*args, **kwargs)
if auth_type == 'local':
username = input('username:').strip()
password = input('password:').strip()
if user == username and pawd == password:
print('wellcome')
res = func(*args, **kwargs)
return res
else:
exit('用户名或密码错误')
elif auth_type == 'ldap':
print('执行ldap里面的验证')
return wrapper
return outer_wrapper
def index():
print('welcome to index page')
#这里传入一个参数是为了理解装饰器传递参数
@auth(auth_type = 'local') #本地认证方式
def home(name):
print('welcome to home page')
return 'from home %s'%name
@auth(auth_type = 'ldap') #远程认证服务器方式
def bbs():
print('welcome to bbs page')
# index()
home('name')
# bbs()
到这里就结束了,是不是很简单。赶紧复制代码,通过DeBug模式调试理解一下。