• 装饰器


    # 装饰器的作用 —— 不想修改函数的调用方式 但是还想在原来的函数前后添加功能
    # 原则: 开放封闭原则
    # 开放 : 对扩展是开放的
    # 封闭 : 对修改是封闭的
    # 语法糖 :@
    import time
    
    
    def timmer(f):    # 装饰器函数
        def inner():
            start = time.time()
            ret = f()       # 被装饰的函数
            end = time.time()
            print(end - start)
            return ret
        return inner
    
    
    @timmer         # 语法糖 @装饰器函数名
    def func():     # 被装饰的函数
        time.sleep(0.01)
        print('老板好同事好大家好')
        return '新年好'
    
    
    ret = func()   # inner()
    print(ret)
    '''
    老板好同事好大家好
    0.010040044784545898
    新年好
    '''

    # 修饰带参数函数的装饰器

    def wrapper(func):   #qqxing
        def inner(*args, **kwargs):
            ret = func(*args, **kwargs)  # 被装饰的函数
            return ret
        return inner
    
    
    @wrapper        # qqxing = wrapper(qqxing)
    def qqxing(a, b):
        print('{} {}'.format(a, b))
    
    
    ret = qqxing(1, {'2': 'hello'})  # inner
    '''
    1 {'2': 'hello'}
    '''

    # functools wraps用法

    from functools import wraps
    
    
    def wrapper(func):  # func = holiday
        @wraps(func)  # 如果不加上wraps语法糖,对于整一个代码来说,holiday函数并不存在了,有的只是被inner函数装饰之后的holiday
        def inner(*args, **kwargs):
            print('在被装饰的函数执行之前做的事')
            ret = func(*args,**kwargs)
            print('在被装饰的函数执行之后做的事')
            return ret
        return inner
    
    
    @wrapper   # holiday = wrapper(holiday)
    def holiday(day):
        '''这是一个放假通知'''
        print('全体放假%s天' % day)
        return '好开心'
    
    
    print('holiday()的名字:', holiday.__name__)
    print('holiday()的注释:', holiday.__doc__)
    ret = holiday(3)   # inner
    print(ret)
    
    '''不加@wraps(func)
    holiday()的名字: inner
    holiday()的注释: None
    在被装饰的函数执行之前做的事
    全体放假3天
    在被装饰的函数执行之后做的事
    好开心
    '''
    
    '''加上@wraps(func)
    holiday()的名字: holiday
    holiday()的注释: 这是一个放假通知
    在被装饰的函数执行之前做的事
    全体放假3天
    在被装饰的函数执行之后做的事
    好开心
    '''

    # 装饰器传参数

    # 如果有500个函数用过一次装饰器了,然后我不想它们走装饰器了,这时候就需要把语法糖给去掉。一个个删除语法糖也要删除500次,过于麻烦,所以就选择在原装饰器外部再加一层用于接收FLAG参数
    import time
    FLAG = False
    
    
    def timmer_out(flag):
        def timmer(func):
            def inner(*args,**kwargs):
                if flag:
                    start = time.time()
                    ret = func(*args,**kwargs)
                    end = time.time()
                    print(end-start)
                    return ret
                else:
                    ret = func(*args, **kwargs)
                    return ret
            return inner
        return timmer
    # timmer = timmer_out(FLAGE)
    @timmer_out(FLAG)    #wahaha = timmer(wahaha)
    def wahaha():
        time.sleep(0.1)
        print('wahahahahahaha')
    
    @timmer_out(FLAG)
    def erguotou():
        time.sleep(0.1)
        print('erguotoutoutou')
    
    
    wahaha()
    erguotou()
    
    '''FLAGE = True时
    wahahahahahaha
    0.10003066062927246
    erguotoutoutou
    0.10085654258728027
    '''
    
    '''FLAGE = False时
    wahahahahahaha
    erguotoutoutou
    '''

    # 多个装饰器装饰一个函数

    def wrapper1(func):
        def inner1():
            print('wrapper1 ,before func')
            ret = func()
            print('wrapper1 ,after func')
            return ret
        return inner1
    
    def wrapper2(func):
        def inner2():
            print('wrapper2 ,before func')
            ret = func()
            print('wrapper2 ,after func')
            return ret
        return inner2
    
    def wrapper3(func):
        def inner3():
            print('wrapper3 ,before func')
            ret = func()
            print('wrapper3 ,after func')
            return ret
        return inner3
    
    @wrapper3
    @wrapper2
    @wrapper1
    def f():
        print('in f')
        return '哈哈哈'
    
    print(f())
    
    '''
    wrapper3 ,before func
    wrapper2 ,before func
    wrapper1 ,before func
    in f
    wrapper1 ,after func
    wrapper2 ,after func
    wrapper3 ,after func
    哈哈哈
    '''

    装饰器题目

    # 1、编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码

    FLAG = False
    
    
    def login(f):
        def inner():
            global FLAG
            if FLAG:
                ret = f()
            else:
                username = input('Please input your username:')
                password = input('Please input your password:')
                with open('login.txt', 'r') as fr:
                    a, b = fr.read().split(' ')
                    if username == a and password == b:
                        FLAG = True
                        ret = f()
                        return ret
                    else:
                        print('username or password error!')
                        return
        return inner
    
    
    @login
    def shoplist_add():
        print('add...')
    
    
    @login
    def shoplist_del():
        print('del...')
    
    
    shoplist_add()
    shoplist_del()
    
    '''
    Please input your username:admin
    Please input your password:123
    add...
    del...
    '''

    # 2、编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件

    import datetime
    
    
    def outer(f):
        def inner():
            with open('log.txt', 'a+') as fw:
                time = datetime.datetime.now()
                fw.write('{0}	{1}
    '.format(time, f.__name__))
                fw.close()
            ret = f()
            return ret
        return inner
    
    
    @outer
    def func1():
        print('func1')
    
    
    @outer
    def func2():
        print('func2')
    
    
    func1()
    func2()
  • 相关阅读:
    文章预告的自我挖坑系列——时尚与深度学习
    文章预告的自我挖坑系列——D3.js 系列之星光闪烁
    时尚与深度学习系列:Fashion forward: Forecasting visual style in fashion
    D3.JS V4 绘制中国地图
    mysql 数据库电脑间迁移
    (QA-LSTM)自然语言处理:智能问答 IBM 保险QA QA-LSTM 实现笔记.md
    博客园里输入latex公式
    理解pytorch中的softmax中的dim参数
    numpy中的广播
    美团餐饮娱乐知识图谱——美团大脑揭秘
  • 原文地址:https://www.cnblogs.com/chuangming/p/9062595.html
Copyright © 2020-2023  润新知