Python装饰器本质上是一个Python函数,是一个特殊的闭包,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,外层函数的返回值是内层函数,装饰器的返回值也是一个函数对象。
装饰器的作用顾名思义,就是装饰其他函数,为其他函数增加额外的功能,有了装饰器,我们就可以抽出大量与函数功能本身无关的代码复用。
▉应用场景:比方说我们有一个打印的功能
def print_now():
print("it's cool")
▉这时,我想加一个需求,穿皮衣,如何加呢
def print_now():
print("it's cool")
print("Wear leather clothes")
ok,看起来很简单,但是如果我要同时给10个,100个函数都添加这个需求呢,并且还要都去打印执行,难道要一个个去添加,去修改原函数的代码吗?
ctrl+V也挺累,而且会造成大量重复的代码,为了减少这个工作量,我们可以重新定义一个函数,避免重复造轮子的现象。
import time
def use_decorate(func):
def cop_time(*args,**kwargs):
start = time.time()
result = func(*args,**kwargs)
stop = time.time()
print(stop - start)
return result
return cop_time
@use_decorate
def index():
print("from index")
index()
以上代码为例,有一个特殊的语法,让我们可以灵活地使用装饰函数。
特殊的语法: 语法糖--- @语法
@装饰器外层函数名
def 原始函数():
pass
我们可以把原始函数看成裸露的肉体,装饰器就是为原始函数加上了外衣,这层外衣为原本的肉体增加了遮羞打扮的功能。
▉一个函数可以添加一个或多个装饰器
▉多个函数也可以使用同一个装饰器
▉对带参的函数进行修饰
def use_decorate(func):
def cop_time(x,y):
print("你看我跑了么")
func(x,y)
return cop_time
@use_decorate
def index(x,y):
print(x,y)
index(1,2)
那么我们如何确定所需参数的数量呢,所以我们用到*args和**kwargs。
def use_decorate(func):
def cop_time(*args,**kwargs):
print("你看我跑了么")
func(*args,**kwargs)
return cop_time
@use_decorate
def index(x,y):
print("我有两个参数是{}and{}".format(x,y))
@use_decorate
def temle(a,b,c):
print("我有三个参数{}and{}and{}".format(a,b,c))
index(1,2)
temle(1,2,3)
由于语法糖@的限制,use_decorate函数只能有一个参数,并且该参数只用来接收被装饰对象的内存地址。
def use_decorate(func):
def cop_time(*args,**kwargs):
result = func(*args,**kwargs)
return result
return cop_time
@use_decorate
def index():
print("from index")
index()
▉在这个例子中:
index的参数什么样子,cop_time的参数就应该什么样子。
index的返回值什么样子,cop_time的返回值就应该什么样子。
index的属性什么样子,cop_time的属性就应该什么样子。
接着,我们做一个小案例,现在有一个需求,增加一个装饰器,为julia添加一个认证的功能,在julia函数执行之前,先增加一个输入账号密码的步骤,认证成功在执行julia。
def clt(clother):
def use_decorate(func):
def cop_time(*args,**kwargs):
name = input("请输入账号:").strip()
pwd = input("请输入密码:").strip()
if name == 'kayidao' and pwd == '123':
result = func(*args,**kwargs)
return result
if clother == 'Nike':
print("欢迎光临Nike")
elif clother == 'Puma':
print("欢迎光临Puma")
elif clother == 'CV':
print("欢迎光临CV")
else:
print("抱歉,你还不是会员")
else:
print("请输入正确的账号或密码")
return cop_time
return use_decorate
@clt(clother='Nike')
def julia(x,y):
print("这是julia会员")
@clt(clother='Puma')
def jack():
print("这是jack会员")
@clt(clother='CV')
def bro():
print("这是CV会员")
julia(1,2)
jack()
bro()
以调用julia为例,当调完clt时,得到的就是一个闭包函数use_decorate,接着use_decorate(julia),把julia这个函数放进来,得到的返回值再返回给julia。
▉总结:
使用装饰器: 需要为核心代码添加的新的功能 但是又不想修改核心代码的内容 就可以添加装饰器。
装饰器的格式:
def 外层函数名(形参):
def 内层函数名(*args, **kwargs):
要添加的内容
result = 原始功能的执行
return result
return 内层函数名
听说长得好看的人都拉到底点了看