装饰器2
-
装饰器:装饰,装修
增加新的功能
-
开放封闭原则:
开放:对代码的拓展封闭。
封闭:对源码的修改是封闭的。
-
装饰器:完全遵循开放封闭原则。
-
装饰器:在不改变原函数的代码以及调用方式的前提下,为其增加新的功能。
-
装饰器就是一个函数
-
装饰器的本质就是闭包。
# 版本四:Python做了一个优化;提出了一个语法糖的概念。标准版装饰器。
import time
def timmer(f):
def inner():
start_time = time.time()
f() # index()
end_time = time.time()
print(f'测试本函数的执行效率:{end_time - start_time}')
return inner
@timmer # index = timmer(index)
def index():
'''有很多代码.....'''
time.sleep(2)
print('欢迎登陆博客园首页')
@timmer
def dariy():
'''有很多代码.....'''
time.sleep(2)
print('欢迎登陆博客园日记页面')
# index = timmer(index) # 每次都得写这句话
index()
# dariy = timmer(dariy)
dariy()
被装饰函数有返回值:
# 版本五:被装饰函数有返回值。
import time
def timmer(f):
def inner():
start_time = time.time()
# print(f'这个是f():{f()}!!!') # index()
r = f()
end_time = time.time()
print(f'测试本函数的执行效率:{end_time - start_time}')
return r
return inner
@timmer # index = timmer(index)
def index():
'''有很多代码.....'''
time.sleep(2)
print('欢迎登陆博客园首页')
return 666
# 加上装饰器不应该改变原函数的返回值,所以666 应该返回给我下面的ret,
# 但是下面的ret实际接收的是inner函数的返回值,而666返回给的是装饰器里面的
# f() 也就是 r 我们现在要解决的问题就是讲r给inner的返回值。
ret = index() # inner()
print(ret)
被装饰函数有参数:
# 版本六:被装饰函数带参数
import time
def timmer(f):
def inner(*args,**kwargs):
# 函数的定义:* 代表聚合 args = ('ww',18)
start_time = time.time()
f(*args,**kwargs) # index()
# 函数的执行:* 代表打散 f(*iterable) ---> f(*('ww',18)) ---> f('ww',18)
end_time = time.time()
print(f'测试本函数的执行效率:{end_time - start_time}')
return inner
@timmer # index = timmer(index)
def index(name):
'''有很多代码.....'''
time.sleep(2)
print(f'欢迎{name}登陆博客园首页')
@timmer
def dariy(name,age):
'''有很多代码.....'''
time.sleep(2)
print(f'欢迎{age}岁的{name}登陆博客园日记页面')
index('kkk') # inner()
dariy('ww',18)
标准装饰器:
# 标准版的装饰器
def wrapper(f):
def inner(*args,**kwargs):
'''添加额外功能:执行被装饰函数之前的操作'''
ret = f(*args,**kwargs)
'''添加额外功能:执行被装饰函数之后的操作'''
return ret
return inner
装饰器的应用:模拟博客园登录
# 装饰器的应用:登录认证
# 模拟博客园登录
def get_user_pwd():
user_dict = {}
with open('register', encoding='utf-8') as f:
for line in f:
line_list = line.strip().split('|')
user_dict[line_list[0].strip()] = line_list[1].strip()
return user_dict
def login():
u_dict = get_user_pwd()
count = 1
while count < 4:
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
if username in u_dict and password == u_dict[username]:
print('登录成功')
status_dict['username'] = username
status_dict['status'] = True
return True
else:
print('用户名密码错误。请重新登录')
count += 1
return False
def register():
print('请完成注册功能')
status_dict = {
'username' : None,
'status' : False,
}
def auth(f):
'''
你的装饰器完成:访问被装饰函数之前,做一步操作。
登录成功:让其访问被装饰的函数,登录没有成功,不让访问。
'''
def inner(*args, **kwargs):
if status_dict['status']:
ret = f(*args, **kwargs)
return ret
else:
if login():
ret = f(*args, **kwargs)
return ret
return inner
@auth
def article():
print('欢迎访问文章页面')
@auth
def comment():
print('欢迎访问评论页面')
@auth
def dariy():
print('欢迎访问日记页面')
article()
comment()
dariy()