zoukankan      html  css  js  c++  java
  • 装饰器(十五)

    import time
    
    def timer(func):
        def swapper(*args,**kargs):
            start_time = time.time()
            res = func(*args,**kargs)
            end_time = time.time()
            print(end_time-start_time)
        return swappe

    装饰器:本质就是函数,用来给其他函数增加 附加功能

    原则:

    1.不修改被修饰函数的源代码

    2.不修改被修饰函数的调用方式

    装饰器 = 高阶函数 +  函数嵌套 +闭包

    高阶函数:

      1.函数的参数是一个函数名

      2.函数的返回值是一个函数名

      3.满足以上两个条件中的一个就是高阶函数

    import time
    
    def foo():
        time.sleep(2)
    
    def test_swapper(func):
        time_start = time.time()
        func()
        time_end = time.time()
        print('函数执行时间:%s' %(time_end - time_start))
    
    test_swapper(foo)  # 修改了函数的调用方式 foo()
    
    '''
    函数执行时间:2.0000498294830322
    '''
    import time
    
    def foo():
        time.sleep(2)
        print('from foo...')
    
    def test_swapper(func):
        time_start = time.time()
        func()
        time_end = time.time()
        print('函数执行时间:%s' %(time_end - time_start))
        return func
    
    foo = test_swapper(foo)
    foo()
    '''
    from foo...
    函数执行时间:2.0009238719940186
    from foo... # 多执行了一次
    '''

    以上说明高阶函数一个人满足不了装饰器的条件

    函数嵌套和函数闭包

    内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包

    闭包似有化了变量,原来需要类对象完成的工作,闭包也可以完成

    闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存

    # 嵌套和闭包
    def father(name):
        def son():
            print('father is %s' % name)
            def grandson():
                print('grandfather is %s' %name)
            grandson()
        son()
        print(locals())
    father('world')
    '''
    father is world
    grandfather is world
    {'son': <function father.<locals>.son at 0x000002287CA55C80>, 'name': 'world'}
    
    '''

    高阶函数 +  函数嵌套 +闭包

    # 框架
    def timer(func):
        def wapper():
            pass
        return wapper()
    import time
    
    def foo():
        time.sleep(2)
        print('from foo...')
    
    def test_swapper(func):
        def son():
            time_start = time.time()
            func()
            time_end = time.time()
            print('函数执行时间:%s' %(time_end - time_start))
        return son
    
    foo = test_swapper(foo)
    #@timer 就相当于 foo = timer(foo)
    foo() ''' from foo... 函数执行时间:2.0008609294891357 '''

    #@timer 就相当于 foo = timer(foo),故可以如下写,就是装饰器的简单实现

    import time
    
    # # 框架
    # def timer(func):
    #     def wapper():
    #         pass
    #     return wapper()
    
    def timer(func):
        def swapper():
            time_start = time.time()
            func()
            time_end = time.time()
            print('函数执行时间:%s' %(time_end - time_start))
        return swapper
    
    @timer
    def foo():
        time.sleep(2)
        print('from foo...')
    
    #foo = timer(foo)     # @timer 就相当于 foo = timer(foo)
    foo()

    加返回值

    import time
    
    # # 框架
    # def timer(func):
    #     def wapper():
    #         pass
    #     return wapper()
    
    def timer(func):
        def swapper():
            time_start = time.time()
            res = func()
            time_end = time.time()
            print('函数执行时间:%s' %(time_end - time_start))
            return res
        return swapper
    
    @timer
    def foo():
        time.sleep(2)
        print('from foo...')
        return 123
    
    #foo = timer(foo)     # @timer 就相当于 foo = timer(foo)
    res = foo()
    print(res)
    '''
    from foo...
    函数执行时间:2.0008599758148193
    123
    '''

    加参数:

    import time
    
    def timer(func):
        def swapper(*args,**kargs):
            start_time = time.time()
            res = func(*args,**kargs)
            end_time = time.time()
            print(end_time-start_time)
    return res
    return swapper @timer def foo(name,age): print('name:%s,age:%s' %(name,age)) time.sleep(1)
    return 123 res = foo(
    'mike',18)

    简单应用

    cur_user = {'name':None, 'certify':False}
    
    # 装饰器可以带参数
    def certify_choice(choice = 'txt'):
        print('认证方式是:%s' %(choice))
        def certify(func):
            def wrapper(*args, **kargs):
                # 如果已经认证就不需要再认证
                if cur_user['name'] == None and cur_user['certify'] == False:
                    name = input('用户名:').strip()
                    password = input('登录密码:').strip()
                    with open('./用户信息','r') as read_file:
                        for info in read_file:
                            eval_info = eval(info)  # 将取出的字符串转为数据类型
                            #print(eval_info['name'],eval_info['password'])
                            if name == eval_info['name'] and int(password) == eval_info['password']:
                                cur_user['name'] = name
                                cur_user['certify'] = True
                                break
                        else:
                            print('当前用户名或密码错误')
                        read_file.close()
                func(*args, **kargs)
            return wrapper
        return certify
    
    @certify_choice()
    def index():
        print('welcome to the page')
    
    @certify_choice()
    def home():
        print('this is home page')
    
    @certify_choice()
    def shopping():
        print('the track has : milk, fruit, ...')
    
    # 这条语句可以用来调试当前程序的函数
    if __name__ == '__main__':
        index()
        home()
        shopping()
    用户信息
    {'name':'a', 'password':111}
    {'name':'b', 'password':222}
    {'name':'c', 'password':333}
    {'name':'d', 'password':444}
  • 相关阅读:
    c++ 反汇编 堆变量
    glibc源码逆向——fread函数
    glibc源码逆向——fopen
    buu查漏补缺刷题(3)
    gyctf_2020_borrowstack
    实现用句柄表反调试
    pwnable_orw 学习shellcraft新花样
    buu查漏补缺刷题(2)
    gdb调试源码
    buu查漏补缺刷题(1)
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/10420073.html
Copyright © 2011-2022 走看看