9月19日装饰器合集
装饰器
装饰器:本质就是一个函数,这个函数有装饰的作用,且装饰的对象也是一个函数
注意点:1.不改变被修饰函数的源代码
2.不改变被修饰函数的调用方式
def A():
    """装饰器"""
    pass
def B():
    """被装饰的函数"""
    pass#源代码不修改
B()#调用方式不改变
例子1:给输出文字的函数添加计时功能
import time#引用time库
def zhuangshi(quyong):#利用闭包的方法将f1整体包入其中,quyong=真正的f1
    """装饰器函数"""
    def f1():#相当于功能
        statr=time.time()#开始时间
        quyong()#相当于将f调用进来
        time.sleep(1)#放慢的时间
        end=time.time()#结束的时间
        print(statr-end)#计算开始和结束之差
    return f1#声明返回值为f1,因为闭包函数返回值必须是嵌套函数的
def f():
    """被装饰的函数"""
    print('jiangjun')
f=zhuangshi(f)#这里令zhuangshi=f也相当于f=f1
f()#使用
从上面代码得出装饰器的关键是闭包函数,这里闭包函数就相当于工具,然后用于被装饰的函数。简白点就是将修饰的函数变相的放到嵌套函数里去使用
例子1的改进
import time
def deco(func):
    def f1(*args,**kwargs):#f1(*args,**kwargs)和index(x=10,a=1)是相同且一一对应的
           print('args:',args)#args=x的值
           print('kwargs:',kwargs)#kwargs=a的值
           start=time.time()
           res=func(*args,**kwargs)
           end=time.time()
           print(end-start)
           return res
    return f1
@deco#语法糖(更精简的代码)#相当于将写好的装饰器用这个代替
def index(x,a):
    print('x',x)
    print('a',a)
    print('hello index')
    time.sleep(1)
    return  123
# index=deco(index)#被语法糖替代
#res=index(1)#被语法糖替代
index(10,1)
例子2:登录购物
def denglu(func):
    def inner(*args,**kwargs):
            zhanghao=input('请输入账号:')
            mima=input('请输入密码:')
            if zhanghao == 'zjb' and mima == '123456':
                print('登录成功')
                res=func(*args,**kwargs)
                return res
            else:
                print('登录失败')
    return inner
@denglu
def shopping():
    print('shopping')
shopping()#这一步必须有
例子三计时
import time
def logger(msg=None):
    def run_time(func):
        def wrapper(*args, **kwargs):
            start = time.time()
            func()  # 函数在这里运行
            end = time.time()
            cost_time = end - start
            print("[{}] func three run time {}".format(msg, cost_time))
        return wrapper
    return run_time
@logger(msg="One")
def fun_one():
    time.sleep(1)
@logger(msg="Two")
def fun_two():
    time.sleep(1)
@logger(msg="Three")
def fun_three():
    time.sleep(1)
fun_one()
fun_two()
fun_three()
通过上面的例子可以得出装饰器的模板
def outter(func):#这里的outter只是名称可以修改
    def inner(*args,**kwargs):#此处的inner也是名称可以修改 
        #加功能区域
        res=func(*args,**kwargs)
        return res
    return inner
@outter
#需要使用此装饰器的函数敲在语法糖下
使用装饰器函数名称()#这一步不能少
三层装饰器
主要作用给双层装饰器加参数,而加参数就要再加一层函数,最外面的那层函数就用来添加参数使用,里面的双层装饰才是用来写功能的,简白点就是多打一层函数为双层装饰器添加参数
例子账号密码
def auth(engine):#将engine这个参数加入而engine有两个结果,每个结果对应的代码块都不同
    def login(func):
        def inner(*args, **kwargs):
            if engine == 'file':#file为engine两个结果中的一个
                zhanghao = input('zhanghao:')
                mima = input('mima:')
                if zhanghao == 'jiang' and mima == '123':
                    print('登录成功')
                    res = func(*args, **kwargs)
                    return res
                else:
                    print('登录失败')
            elif engine == 'db':#db为engine两个结果中的一个
                print('账号密码来自于数据库,非法请求')
        return inner
    return login
@auth('file')#语法糖相当于包含了两段代码,且file可以换成db
def shopping():
    print('shopping')
#login=auth('db') 被语法糖省略这步让login和auth相等,这里的db可以换成file   
#shopping=login(shopping)  被语法糖省略这步让shopping和login相等
shopping()
通过上面知道装饰器必须是函数嵌套,当装饰器这个嵌套函数的功能设计好了之后再添加到需要的函数内,
这时候需要给将此函数以参数的形式带入到装饰器内。

                
            
浙公网安备 33010602011771号