当一个被装饰的对象同时叠加多个装饰器时
装饰器的加载顺序是:由下而上
装饰器的执行顺序是:由上而下
加载装饰器就是将原函数名与装饰器内部的wrapper函数进行偷梁换柱
执行装饰器实际上就是执行装饰器内部的wrapper函数。
我们来看下面这段代码
def decorator_a(fun):
print('Get in decorator_a')
def inner_a(*args, **kwargs):
print('Get in inner_a')
res = fun(*args, **kwargs)
return res
return inner_a
def decorator_b(fun):
print('Get in decorator_b')
def inner_b(*args, **kwargs):
print('Get in inner_b')
res = fun(*args, **kwargs)
return res
return inner_b
@decorator_a
@decorator_b
def f(x):
print('Get in f')
return x * 2
f(2)
看下执行结果:
Get in decorator_b
Get in decorator_a
Get in inner_a
Get in inner_b
Get in f
多个装饰器练习
import functools
import inspect
def is_admin(fun):
@functools.wraps(fun)
def wrapper(*args,**kwargs):
#inspect.getcallargs返回一个字典,key值是形参,value值
#是对应的实参{'name':'root'}
inspect_res = inspect.getcallargs(fun,*args,*kwargs)
print('inspect的返回值: %s' %inspect_res)
if inspect_res.get('name') == 'root':
res = fun(*args,**kwargs)
return res
else:
print('not root user!')
return wrapper
login_session = ['root', 'redhat', 'westos']
def is_login(fun):
@functools.wraps(fun)
def wrapper(*args,**kwargs):
if args[0] in login_session:
res = fun(*args,**kwargs)
return res
else:
print('Error:%s未登录' %args[0])
return wrapper
@is_login
@is_admin
def add_student(name):
print('添加学生信息...')
add_student('linux')