装饰器:本质是一个闭包
作用:在不改变原有函数调用的情况下,给函数增加新的功能
雏形:
def wrapper(fn): wrapper: 装饰器, fn: 目标函数
def inner(*args, **kwargs):
# 在目标函数执行之前...
res = fn(*args, **kwargs) 执行目标函数
# 在目标函数执行之后...
return res
return inner # 千万别加小括号
@wrapper
def target():
pass
taget() # => inner()
一个函数可以被多个装饰器修饰。
@wrapper1
@wrapper2
def target():
pass
规则和规律 wrapper1 wrapper2 target wrapper2 wrapper1
示例:
def ggg(fn):
def inner(*args, **kwargs):
print('开始')
res = fn(*args)
print('结束')
return res
return inner
@ggg
def func(user, passw):
print(f'账户登录 {user}: {passw}')
return '123'
print(func('zhangsan', 123))
'''
解析:
运行fun c('zhangsan', 123)时,先调用ggg(@表示要先进去后面函数),进而ggg返回inner,即func表示为inner,进一步调用inner。
'''
开始
账户登录 zhangsan: 123
结束
123
多装饰器修饰
def wrapper1(fn):
def inner(*args, **kwargs):
print('wrapper1进入')
res = fn(*args, **kwargs)
print('wrapper1结束')
return res
return inner
def wrapper2(fn):
def inner(*args, **kwargs):
print('wrapper2进入')
res = fn(*args, **kwargs)
print('wrapper2结束')
return res
return inner
@wrapper1 # target = wrapper1(wrapper2.inner) => target = wrapper1.inner
@wrapper2 # target = wrapper2(target)
def target():
print('目标函数')
target()
wrapper1进入
wrapper2进入
目标函数
wrapper2结束
wrapper1结束
登录系统实战
login_flag = False
def log_verify(fn):
def inner(*args, **kwargs):
global login_flag
if not login_flag:
# 登录校验
print('还未完成用户登录操作')
username = input(">>>")
password = input(">>>")
while True:
if username == "admin" and password == "123":
login_flag = True
print("登录成功")
break
else:
print("登录失败,用户名或密码错误")
res = fn(*args, **kwargs)
return res
return inner
@log_verify
def add():
print('添加员工信息')
@log_verify
def delete():
print('删除员工信息')
@log_verify
def upd():
print('更新员工信息')
@log_verify
def search():
print('查询员工信息')
add()
delete()
upd()
search()
本文探讨了装饰器的本质,它是如何通过闭包实现不改变原函数功能的附加行为。通过实例演示了单装饰器和多装饰器的使用,以及在登录验证场景中的实际应用。
17万+

被折叠的 条评论
为什么被折叠?



