作用:提到代码的重用性,可以在不改变原函数代码的前提下,为该函数增加新的功能
应用场景:权限校验,日志处理
注:装饰器返回函数对象或者类对象。装饰器是一个函数或者类,谁调用它就可以用它的功能。 注: *args, **kwargs #
args是一个数组,kwargs一个字典
需求1: 用户登陆验证的装饰器is_login
1). 如果用户登陆成功, 则执行被装饰的函数;
2). 如果用户登陆不成功, 则执行登陆函数需求2: 判断登陆用户是否未管理员is_admin(此处管理员只有一个为:admin用户)
1).如果用户为管理员, 则执行被装饰的函数;
2).如果用户不是管理员, 则报错;
import functools
login_users = ['admin', 'root']
def is_admin(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
if kwargs.get('name') == 'admin':
res = fun(*args, **kwargs)
return res
else:
return 'error'
return wrapper
def is_login(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
if kwargs.get("name") in login_users:
res = fun(*args, **kwargs)
return res
else:
res = login()
return res
return wrapper
@is_admin
@is_login
def writeBlog(name):
return "编写博客"
def login():
return "登陆..."
print(writeBlog(name='admin'))
# 注:functools.wraps,wraps本身也是一个装饰器,
它能把原函数的元信息拷贝到装饰器里面的 func 函数中,
这使得装饰器里面的 func 函数也有和原函数一样的元信息了。
问题:如何给函数添加日志
import functools
import time
def log(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
start_time = time.time()
res = fun(*args, **kwargs)
end_time = time.time()
print(time.ctime(), fun.__name__, (end_time - start_time), res)
return res
return wrapper
@log
def sum(x, y):
time.sleep(1)
return x + y
print(sum(2, 1))