/ 2019-06-26
上面的写法写死了func = index,我们还可以优化下:
def timer(func): # 传一个func参数和下面func = index一样都是在my_index函数内部定义了一个局部变量
# func = index # 在外部函数定义一个局部变量
def wrapper(): # 设置一个参数
start_time = time.time()
func() # 在这个函数内部调用下func
stop_time = time.time()
print("耗时{}秒。".format(stop_time - start_time))
return wrapper好了,我们刚刚就已经写好了一个装饰器。
验证一下,我们的成果:
index = timer(index)
index()
输出:
欢迎访问首页。
耗时1.0029211044311523秒。
没有修改原函数的源代码。
没有修改原函数的调用方式。(虽然此时的index已不再是原来的index,但是并没有修改调用index的方式。)
现在我们来验证下我们的成果:
import time
import random
def index():
time.sleep(random.randrange(1, 5)) # 随机sleep几秒
print("欢迎访问首页。")
def home():
time.sleep(random.randrange(1, 5)) # 随机sleep几秒
print("欢迎访问个人主页。")
def timer(func): # 传一个func参数和下面func = index一样都是在my_index函数内部定义了一个局部变量
def wrapper(): # 设置一个参数
start_time = time.time()
func() # 在这个函数内部调用下func
stop_time = time.time()
print("耗时{}秒。".format(stop_time - start_time))
return wrapper
index = timer(index)
home = timer(home)
index()
home()
输出:
欢迎访问首页。
耗时3.0008788108825684秒。
欢迎访问个人主页。
耗时3.00280499458313秒。
简直完美,功能实现可以装饰任意函数。就是写起来有点麻烦。Python中支持更简便的写法,往下看。
在被装饰对象的正上方单独的一行写上@装饰器名即可,即:
用装饰器的语法修改一下我们上面的代码:
def timer(func): # 传一个func参数和下面func = index一样都是在my_index函数内部定义了一个局部变量
def wrapper(): # 设置一个参数
start_time = time.time()
func() # 在这个函数内部调用下func
stop_time = time.time()
print("耗时{}秒。".format(stop_time - start_time))
return wrapper
@timer # 相当于做了 index = timer(index) 操作
def index():
time.sleep(random.randrange(1, 5)) # 随机sleep几秒
print("欢迎访问首页。")
让我们练习写一个装饰器来巩固下上面学习的内容:给 index 和 home 函数加一个验证功能,用户名和密码正确才打印欢迎信息。否则打印“验证失败”。
先写一个用于验证的装饰器:
def auth(func):
def wrapper():
name = input("用户名:").strip()
password = input("密码:").strip()
if name == "Andy" and password == "123":
print("验证成功!")
func()
else:
print("验证失败!")
return wrapper
测试一下:
@auth
def index():
time.sleep(random.randrange(1, 5)) # 随机sleep几秒
print("欢迎访问首页。")
index()
输出:
用户名:Andy
密码:123
验证成功!
欢迎访问个人主页。
基本的装饰器介绍到这里就结束了。后面还会有多个装饰器及带参数的装饰器。
(0)