python装饰器是我们程序开发过程中经常使用的功能,在不修改原函数的基础上,对原函数添加新的功能,是开放封闭原则的典型代表,当程序成千上万行时,修改一个函数,有时候所带来的结果可能会让人摸不着头绪,这时候,运用装饰器,就变得非常便利了
简单来说,python装饰器就是把一个函数当作参数返回一个替代版的函数,本质上就是一个返回函数的函数
装饰器的引入
话不多说,直接上代码def fun():
print("this is a dog ")
def dog(fun1):
print("the dog is barking")
fun1()
fun = dog(fun)
这样子就只是执行了,在一个函数中调用了原来的函数,对吧,来看下面的例子
def fun1():
print("this is a dog ")
return "this is a dog"
def dog(fun):
def Dog():
print("the dog is barking")
fun()
#这是化妆的结果
Dog()
dog(fun1)
这还只是调用,继续往下看
def fun1():
print("this is a dog ")
return "汪汪"
def dog(fun):
def Dog():
print("the dog is barking")
fun()
#注意,我这块返回的是一个函数名称
return Dog
#fun1在这块可以理解为fun1的加强版本,fun1就是Dog()函数
fun1 = dog(fun1)
fun1()
这就是一个最最最简单的装饰器,接下来就是很简单的一个装饰器的常用形式
def dog(fun):
def Dog():
print("the dog is barking")
fun()
return Dog
#使用@符号将装饰器应用到函数
@dog #fun1 = dog(fun1)
def fun1():
print("this is a dog ")
return "this is a dog"
fun1()
@符号在这里就相当于fun1 = dog(fun1),不过,使用@时,下面必须跟的是被装饰的函数,若语句为fun1 = dog(fun1),则要用在被装饰函数之后,否则报错。
来个通俗易懂的装饰器模型吧
def wraper(func):
def inner(*args, **kwargs):
print("执行函数前扩展的内容")
ret = func(*args,**kwargs)
print("执行函数后扩展的内容")
return ret
return inner
@wraper
def index(name, age):
print("我叫%s,今年%d岁" % (name, age))
index('tjb', 22)
多个装饰器装饰同一个函数
import time
def deco01(func):
def wrapper(*args, **kwargs):
print("this is deco01")
startTime = time.time()
ret=func(*args, **kwargs)
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
print("deco01 end here")
return ret
return wrapper
def deco02(func):
def wrapper(*args, **kwargs):
print("this is deco02")
ret=func(*args, **kwargs)
print("deco02 end here")
return ret
return wrapper
@deco01
@deco02
def func(a,b):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b))
func(3,4)
带参数的装饰器
带参数的装饰器,需要三层函数,第一层函数返回第二层函数的函数名,第二层函数返回第三层函数的函数名,第三层函数返回被装饰的函数调用。如:def func1(outer):
def func2(f):
def func3(*args,**kwargs):
print("参数:",outer)
print("装饰之前的部分")
a=f(*args,**kwargs)
print('装饰之后的部分')
return a
return func3
return func2
@func1("hello")
def func(a,b):
print("a+b=",a+b)
func(1,2)
#结果
参数: hello
装饰之前的部分
a+b= 3
装饰之后的部分
类装饰器
class decor:
def __call__(self, func):
def f(*args,**kwargs):
print('装饰前')
res=func()
print('装饰后')
return res
return f
@decor()
def func():
print(666)
func()
类装饰器需要用到__call__这个魔法方法,@符号需要加括号