装饰器
1.1 作用:
-
在函数名以及函数体不被改变的的前提下,给函数附加一些额外的操作代码
-
综合能力
- 高阶函数
- 闭包
- 函数不定长参数(元组、字典)
- 拆包,装包
- 开闭原则(对已有代码逻辑修改的封闭,对新功能添加开放)
- 单一原则(每个函数功能单一,即发图片就是发图片,不能包含登录检测)
1.2 语法
# 给fss函数增加一些额外的功能,
# 1. 函数名字不能发生改变
# 2. 函数体内部的代码不能发生改变
def check(func):
print("增加功能")
def inner():
print("登录验证操作....")
func()
return inner
@check
def fss():
print("发说说")
fss()
1.3 案例
- 点击不同的按钮,执行对应操作;
1. 点击发送说说按钮,发送说说文本
2. 点击发图片按钮,发送图片
3. 在上述功能已经完善的情况下,添加发送前检测登录功能
- 完成1、2 功能代码
# 定义两个功能函数
def fss():
checkLogin()
print("发说说")
def ftp():
checkLogin()
print("发图片")
def checkLogin():
print("登录验证...")
# 相关的逻辑代码
btnIndex = 2
if btnIndex == 1:
fss()
else:
ftp()
- 通过装饰器,添加功能3检测登录
def checkLogin(func):
def inner():
print("登录验证...")
func()
return inner
# 定义两个功能函数
@checkLogin
def fss():
print("发说说")
# @checkLogin 这个写法相当于 fss = checkLogin(fss)
@checkLogin
def ftp():
print("发图片")
# ftp = checkLogin(ftp)
# 相关的逻辑代码
btnIndex = 1
if btnIndex == 1:
fss()
else:
ftp()
1.4 注意
- 装饰器的执行时间,是立即执行
1.5 进阶
- 装饰器的叠加
1. 从上到下装饰
2. 从下到上执行
- 对有参函数进行修饰
1. 无论什么场景,保证函数调用参数个数一致
2. 为了通用,可以使用不定长参数,结合拆包操作进行处理
def zsq(func):
def inner(*args, **kwargs):
print("_" * 30)
# print(args, kwargs)
func(*args, **kwargs)
return inner
@zsq
def pnum(num, num2, num3):
print(num, num2, num3)
@zsq
def pnum2(num):
print(num)
pnum(123, 222, num3=666)
pnum2(999)
- 对有返回值的函数进行修饰
1. 无论什么场景,保证函数返回值一致
def zsq(func):
def inner(*args, **kwargs):
print("_" * 30)
# print(args, kwargs)
res = func(*args, **kwargs)
return res
return inner
@zsq
def pnum(num, num2, num3):
print(num, num2, num3)
return num + num2 + num3
@zsq
def pnum2(num):
print(num)
res1 = pnum(123, 222, num3=666)
res2 = pnum2(999)
print(res1, res2)
- 带有参数的装饰器
1. 通过 @装饰器(参数)的方式,调用这个装饰器选择函数,并传递参数,然后把返回值,再次充当装饰器进行使用
2. 先计算@后面的内容,把这个内容当做是装饰器
# 装饰器获取器,动态按需选择装饰器
def getzsq(char):
def zsq(func):
def inner():
print(char * 30)
func()
return inner
return zsq
# 不同的单个相似功能的装饰器
# def zsqe(func):
# def inner():
# print("=" * 30)
# func()
# return inner
# def zsqs(func):
# def inner():
# print("*" * 30)
# func()
# return inner
@getzsq("*") # f1 = zsq(f1)
def f1():
print("666")
f1()
网友评论