5.15 装饰器
- 开放封闭原则
- 封闭原则: 不改变源码.
- 开放原则: 更新增加一些额外的功能.
Python中装饰器:完美的诠释开放封闭原则
装饰器就是一个函数:装饰一个函数,在不改变原函数的源码以及调用方式的前提下,给其增加一个额外的功能
# 装饰器模板
def warpper(f):
def inner(*args,**kwargs): # * 在定义函数: 聚合
'''被装饰函数执行前的操作'''
ret = f(*args,**kwargs) # * 在执行函数: 打散
'''被装饰函数执行后的操作'''
return ret
return inner
-------------------------------------------------------
@warpper # func = warpper(func)
def func(*args,**kwargs):
pass
func(a,b)
# 博客园的登录认证 *****
# 设置状态
dic_status = {'name':None,'status':False}
# 读取文件内容,字典推导式
def get_dic_user_pwd():
with open('register',mode='r',encoding='utf-8') as f:
return {i.strip().split('|')[0]:i.strip().split('|')[1] for i in f}
# 三次重复登录
def login(dic_user_pwd):
dic = dic_user_pwd()
count = 1
while count <= 3:
username = input('请输入用户名').strip()
password = input('请输入密码').strip()
if username in dic and password == dic[username]:
dic_status['username'] = username
dic_status['status'] = True
return True
count += 1
return False
# 登录认证
def auth(func):
def inner(*args,**kwargs):
'''要进行登陆认证:
有两个分支:
1,如果之前登陆成功了,直接访问。
2,如果这是之前没有登陆过,先进行三次登陆。
'''
if dic_status['status']:
ret = func(*args,**kwargs)
return ret
else:
if login(get_dic_user_pwd):
ret = func(*args, **kwargs)
return ret
return inner
@auth
def article():
print('欢迎访问文章页面')
article()
@auth
def diary():
print('欢迎访问日记页面')
diary()
@auth
def comment():
print('欢迎访问评论页面')
comment()
带参数的装饰器 -- 开发思路:增强耦合性
@wrapper_out(n)
- 执行 wrapper_out(参数) 这个函数,把相应的参数传给n,并且得到返回值--wrapper.
- 将@ 与wrapper 结合,得到标准版的装饰器,按照装饰器的执行流程执行
def wrapper_out(n):
def wrapper(f):
def inner(*args,**kwargs)
uesrname = input('输入用户名')
password = input('输入密码')
with open(n,mode='r',encoding='utf-8') as f1:
for i in f1:
user,pwd = i.strip().split('|')
if username = user and password = pwd:
print('登录成功')
ret = f(*args,**kwargs)
return ret
return False
return inner
return wrapper
@wrapper_out('qq')
def qq():
print('成功登录QQ')
qq()
@wrapper_out('tiktok')
def tiktok():
print('成功访问抖音')
tiktok()
多个装饰器装饰一个函数
def wrapper1(func1): # func1 = f原函数
def inner1():
print('wrapper1 ,before func') # 2
func1()
print('wrapper1 ,after func') # 4
return inner1
def wrapper2(func2): # func2 = inner1
def inner2():
print('wrapper2 ,before func') # 1
func2() # inner1
print('wrapper2 ,after func') # 5
return inner2
# 先执行离被装饰函数最近的装饰器,装饰器结束之后执行函数f()
@wrapper2 # 第二步 f = wrapper2(f) 里面的f = inner1 / 外面的 f = inner2
@wrapper1 # 第一步 f = wrapper1(f) 里面的f = func1 / 外面的 f = inner1
def f():
print('in f') # 3
f() # inner2