装饰器
定义:装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
def des(fun): #传递的函数是需要装饰的函数
def wrapper():
print('国庆节快乐......')
fun()
print('欢度国庆......')
return wrapper #返回值是一个函数对象
@des # fun = desc(fun)
def fun():
print('login')
fun()
结果:
如何使函数有返回值
解决方法:给装饰器中传入的函数的返回值给一个接收变量,然后在装饰器函数的内置函数中,加return语句,返回返回值。
def dec(fun):
def wrapper(*args,**kwargs): #*args,*kwargs是对被装饰函数所需的参鼠进行接收
print('你好')
res = fun(*args) #res对传入的数据进行接收,*args,**kwargs是对数据进行解包
return res
return wrapper
@dec
def fun(x,y):
return pow(x,y)
print(fun(2,2))
结果:
如何被装饰函数使函数名和函数的文档信息保持不变
解决方案:用内置模块中的 装饰器(functools.wraps( ))修饰本程序装饰器的内置函数
import functools
import time
def dec(fun):
@functools.wraps(fun)
def wrapper(*args,**kwargs):
start_time = time.time()
res = fun(*args)
end_time = time.time()
print('时间为:%.6f' %(end_time-start_time))
return res
return wrapper
@dec
def fun(x,y):
'''
这是一个求绝对值的函数
'''
return pow(x,y)
print(fun(-1,2))
print(fun.__name__)
print(fun.__doc__)
结果:
装饰器的第二种方式
在装饰器中,通过判断语句来决定是否执行函数
import functools
usernames = ['root','linux']
def des(fun):
@functools.wraps(fun)
def wrapper(*args,**kwargs):
if kwargs.get('name') in usernames:
res = fun(*args,**kwargs)
return res
else:
login()
return wrapper
@des
def write_cslog(*args,**kwargs):
print('写博客')
def login():
print('请登陆')
write_cslog(name='root')
结果:
向装饰器中传入参数
装饰器的语法允许我们在调用时,提供其它参数
import functools
import time
def log(find):
def des(fun):
@functools.wraps(fun)
def wrapper(*args,**kwargs):
start_time = time.time()
res = fun(*args,**kwargs)
end_time = time.time()
print('<日值级别为:%s>,;运行时间为:%.6f' %(find,end_time-start_time))
return res
return wrapper
return des
@log('find') ## log("find")返回值是des; log=log(add)
def mypow(x,y):
return pow(x,y)
print(mypow(2,2))
结果:
带有多个装饰器的函数
def makebold(fun):
print("bold1")
def wrapper1(*args, **kwargs):
print("bold2")
return fun(*args, **kwargs) # wrapper
return wrapper1
def makei(fun): # fun=login
print("i1")
def wrapper(*args, **kwargs):
print("i2")
return fun(*args, **kwargs)
return wrapper
# 当有多个装饰器时, 从下到上调用装饰器,
# 真实wrapper内容执行是从上到下执行.
@makebold # login = makebold(login) # login为wrapper1
@makei # login = makei(login) # login为wrapper
def login():
return "登陆"
print(login())
结果: