is_admin装饰器
import functools
import inspect
def is_admin(fun): #fun=add_student
@functools.wraps(fun)
def wrapper(*args,**kwargs): #kwargs={'name':'root'}
#inspect.getcallargs返回一个字典,key值为:形参, value值为对应的实参
inspect_res=inspect.getcallargs((fun,*args,**kwargs))
print('inspect的返回值:%s'%(inspect_res))
if inspect_res.get('name')=='root':
temp=fun(*args,**kwargs)
return temp
else:
print('not root/admin user,not permission add student')
return wrapper
@is_admin
def add_student(name):
print('添加学生信息')
add_student('redhat')
探究多个装饰器的执行顺序
def decorator_a(func):
print('Get in decorator_a')
def inner_a(*args,**kwargs):
print('Get in inner_a')
return func(*args,**kwargs)
return inner_a
def decorator_b(func):
print('Get in decortor_b')
def inner_b(*args,**kwargs):
print('Get in inner_b')
return func(*args,**kwargs)
return inner_b
#当有多个装饰器时,从下到上调用装饰器:
@decorator_b #func=decorator_b(inner_a) #func=inner_b
@decorator_a #func=decorator_a(func) #func=inner_a
def f(x):
print('Get in f')
return x*2
f(1) #inner_b(1)
多个装饰器的应用
总结:在实际应用的场景中,会采用多个装饰器先验证是否登陆成功,再验证权限是否足够
import functools
import inspect
def is_admin(fun): #fun=add_student
@functools.wraps(fun)
def wrapper(*args,**kwargs): #kwargs={'name':'root'}
#inspect.getcallargs返回一个字典,key值为:形参,value值为对应的实参
inspect_res=inspect.getcallargs(fun,*args,**kwargs)
print('inspect的返回值:%s'%(inspect_res))
if inspect_res.get('name')=='root':
temp=fun(*args,**kwargs)
return temp
else:
print('Error:not root/admin user,no permission add student')
return wrapper
login_session=['root','admin','redhat']
def is_login(fun):
@functools.wraps(fun)
def wrapper(*args,**kwargs):
if args[0] in login_session:
temp=fun(*args,**kwargs)
return temp
else:
print('Error:%s未登陆'%(args[0]))
return wrapper
@is_login
@is_admin #is_admin
带参数的装饰器
#创建add_log装饰器,被装饰的函数打印日志信息:
#日志格式为:[字符串时间] 函数名:xxxx,运行时间:xxx,运行返回值结果xxxx
import time
import functools
import random
#带有参数的装饰器,在原有装饰器外面加一个函数,用来接受装饰器参数的
def addLog(type):
def add_log(fun):
@functools.wraps(fun)
def wrapper(*args,**kwargs):
start_time=time.time()
res=fun(*args,**kwargs)
end_time=time.time()
print('日志信息:[%s] [%s] %s 运行时间为%.5f s 运行结果为%s'
%(type.title(),time.ctime(),fun.__name__,end_time-start_time,res))
return res
return wrapper
return add_log
@addLog('warn')
def hello():
time.sleep(random.random())
return 'hello'
print(hello())
带有参数装饰器练习-----参数检测
# 1. 基础版(无参数的装饰器)
编写装饰器required_ints, 条件如下:
1). 确保函数接收到的每一个参数都是整数;
2). 如果参数不是整形数, 打印 TypeError:参数必须为整形
def required_int(fun):
def wrapper(*args,**kwargs):
for i in args:
if not isinstance(i,int):
print('TypeError:参数必须是整形')
break
else:
res=fun(*args,**kwargs)
return res
return wrapper
@required_int
def add(x,y):
return x+y
print(add(1,3))
# 2. 升级版(有参数的装饰器)
编写装饰器required_types, 条件如下:
1). 当装饰器为@required_types(int,float)确保函数接收到的每一个参数都是int或者float类型;
2). 当装饰器为@required_types(list)确保函数接收到的每一个参数都是list类型;
3). 当装饰器为@required_types(str,int)确保函数接收到的每一个参数都是str或者int类型;
4). 如果参数不满足条件, 打印 TypeError:参数必须为xxxx类型
def required_types(*types):
def required(fun):
def wrapper(*args,**kwargs):
#判断每一个元素都是整形
for i in args:
if not isinstance(i,types):
print('TypeError:参数必须是%s类型'%(types))
break
else:
res=fun(*args,**kwargs)
return res
return wrapper
return required
@required_types(int,float)
def add(x,y):
return x+y
print(add(1,3e+7))
装饰器总结
1. 什么是装饰器?
# 2.
@add_log # fun = add_log(fun)
def fun():
return "fun"
#3. 装饰器模板
## 3-1. 装饰器函数不加参数:
def 装饰器名称(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
# 函数执行之前做的操作
res = fun(*args, **kwargs)
# 函数执行之前做的操作
return res
return wrapper
## 3-2. 装饰器函数加参数:
def 装饰器名称(*args, **kwargs):
def inner(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
# 函数执行之前做的操作
res = fun(*args, **kwargs)
# 函数执行之前做的操作
return res
return wrapper
return inner
# 4. import functools
@functools.wraps(f)
# 5. import inspect
inspect.getcallargs(f,*args,**kwargs)
# 6. 多个装饰器时
@deco1 #fun = deco1(fun)
@deco2 # fun = deco2(fun)
def fun():
return "fun"