一、装饰器是什么?
给原来的函数添加额外功能,但不需要修改原来函数的代码以及调用方式
二、装饰器的原则:
1.不修改原来函数
2.不修改原来函数的调用方式
三、装饰器的实现
1.不带参数的装饰器:
def decorat(func):
print("xxxx")
def wrapper():
print("comein wrapper")
start = time.time()
func()
end = time.time()
print("fun1函数执行了{}s".format(end-start))
return wrapper
@decorat
def fun1():
time.sleep(3)
print("func1...")
return "hh"
fun1()
2.装饰器本身带参数:
def decorat2(unit):
print("unit")
def outter(func):
def wrapper():
print("comein wrapper")
start = time.time()
func()
end = time.time()
print("fun1函数执行了{}{}".format(end-start,unit))
return wrapper
return outter
@decorat2(unit='s')
def fun3():
time.sleep(3)
print("func2...")
return "hh"
fun3()
3.被装饰的函数带参数
def decorat1(unit):
print("unit")
def outter(func):
def wrapper(*args, **kwargs):
print("comein wrapper")
start = time.time()
res = func(*args, **kwargs)
print("res:",res)
end = time.time()
print("fun1函数执行了{}{}".format(end-start,unit))
return res
return wrapper
return outter
@decorat1(unit='s')
def fun2(name):
time.sleep(3)
print("func2...",name)
return "hh"
res = fun2('hello world')
print(res)
def wrapper(func):
def inner(*args):
print("我要开始计算了")
res = func(*args)
print("计算玩了哈")
return res
return inner
f = wrapper(add)
f(1,2)
def wrapper(func):
def inner(*args):
print("我要开始计算了")
res = func(*args)
print("计算玩了哈")
return res
return inner
@wrapper
def add(x,y):
print("{}+{}={}".format(x,y,x+y))
add(2,3)
四、写装饰器的方法
1.首先定义一个装饰器函数,并且接受一个函数名作为形参(该函数就是被装饰函数,通过语法糖可自动实现赋值,我们只需要定义一个函数名形参即可)
2.写一个wrapper函数,嵌套函数,这个嵌套函数负责两件事,一是将新增功能的代码写在里面,二是通过外层装饰器中传入的函数名调用被装饰函数。
3.在外层装饰器函数中返回wrapper函数的地址。
4.如果被装饰函数带参数,则需要在调用被装饰函数的wrapper函数中加上类似*args, **kwargs的形参并在调用被装饰函数时传给被装饰函数。
5.如果装饰函数本身带参数,则需要在wrapper函数外面再增加一个outer_wrapper,并将被装饰函数的函数名传给outer_wrapper。装饰函数本身的参数则传给最外层的函数名。
6.如果被装饰函数带返回值,则在内部调用被装饰函数的wrapper函数中也要把返回值return回来。