装饰器

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"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值