zoukankan      html  css  js  c++  java
  • Python学习第十一课——装饰器

    #装饰器:本质就是函数,为其他函数附加功能
    原则:
    1、不修改被修饰函数的源代码
    2、不修改被修饰函数的调用方式

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

    #高阶函数

    '''
    高阶函数定义:
    1、函数接受的参数是一个函数名
    2、函数的返回值是一个函数名
    3、满足上述条件任意一个,都可称之为高阶函数
    '''
    
    
    # 函数接受的参数是一个函数名的情况下,要改变函数的调用方式
    def foo():
        time.sleep(2)
        print("憨憨你好")
    
    
    def test(func):
        print(func)
        start_time=time.time()
        func()
        stop_time=time.time()
        print('函数的运行时间是%s' %(stop_time-start_time))
    
    
    test(foo) # 修改了函数的调用方式
    
    
    # 函数的返回值是一个函数名,此时不需要改变函数调用方式
    def foo():
        print('from the foo')
    
    
    def test(func):
        return func
    
    
    foo = test(foo)
    foo()
    
    
    def foo():
        time.sleep(3)
        print('来自foo')
    
    
    # 完成装饰器添加功能
    # 该写法多运行了一次  所以高阶函数无法满足装饰器运用
    def timmer(func):
        start_time = time.time()
        func()
        stop_time = time.time()
        print('函数运行时间%s' % (stop_time - start_time))
        return func
    
    
    foo = timmer(foo)
    foo()

    #函数镶嵌

    def father(name):
        print('from father %s' % name)
    
        def son():
            print('他的爸爸是%s' % name)
    
            def grandson():
                print('他的爷爷是%s' % name)
    
            grandson()
    
        son()
    
    
    father('憨憨')

    #装饰器例子

    # 打印1+2+3+..+100 并且打印出运行时间
    import time
    
    def cal(l):
        start_time = time.time()
        res = 0
        for i in l:
            time.sleep(0.01)
            res += i
        stop_time = time.time()
        print("函数的运行时间是%s" % (stop_time - start_time))
        return res
    
    
    print(cal(range(100)))
    
    def timmer(func):  # 计算函数运行时间功能
    
        def wrapper(*args, **kwargs):
            start_time = time.time()
            res = func(*args, **kwargs)
            stop_time = time.time()
            print('函数运行的时间是%s' % (stop_time - start_time))
            return res
    
        return wrapper
    
    
    @timmer  # 在不动原函数的基础上  为该函数加上其他功能
    def cal(f):
        res = 0
        for i in f:
            time.sleep(0.1)
            res += i
        return res
    
    
    print(cal(range(100)))

    #函数镶嵌 装饰器的实现

    def timmer(func):
        def wrapper():
            start_time = time.time()
            func()  # 运行的就是test
            stop_time = time.time()
            print('运行时间是%s' % (stop_time - start_time))
    
        return wrapper
    
    
    @timmer  # 相当于 test=timmer(test)
    def test():
        time.sleep(3)
        print('test已经运行')
    
    
    test()

    # 例子1:为京东商城中的一些方法加上验证装饰器

    # 将下列方法加上验证装饰器
    current_dic = {'username': None, 'login': False}
    
    user_list = [
        {'name': 'hanhan', 'pwd': '123'},
        {'name': 'amei', 'pwd': '1234'},
        {'name': 'ahao', 'pwd': '123456'}
    ]
    
    
    def yanzheng(func):
        def wrapper(*args, **kwargs):
            if current_dic['username'] and current_dic['login']:
                res = func(*args, **kwargs)
                return res
            username = input('输入用户名:').strip()
            pwd = input('输入密码:').strip()
            for user_dic in user_list:
                if username == user_dic['name'] and pwd == user_dic['pwd']:
                    current_dic['username'] = username
                    current_dic['login'] = True
                    res = func(*args, **kwargs)
                    return res
            else:
                print('输入的用户名和密码有误')
    
        return wrapper
    
    
    @yanzheng
    def index():
        print('欢迎来到京东商城')
    
    
    @yanzheng
    def jiaose(name):
        print('进入%s页面' % (name))
    
    
    @yanzheng
    def shopping_car(name):
        print('%s购物车里面有[%s,%s,%s]' % (name, '飞机', '火箭', '娃娃'))
    
    
    index()
    jiaose('管理员')
    shopping_car('产品经理')
  • 相关阅读:
    PHP实现无限极分类
    html2canvas生成并下载图片
    一次线上问题引发的过程回顾和思考,以更换两台服务器结束
    Intellij IDEA启动项目报Command line is too long. Shorten command line for XXXApplication or also for
    mq 消费消息 与发送消息传参问题
    idea 创建不了 java 文件
    Java switch 中如何使用枚举?
    Collections排序
    在idea 设置 git 的用户名
    mongodb添加字段和创建自增主键
  • 原文地址:https://www.cnblogs.com/pyhan/p/12240195.html
Copyright © 2011-2022 走看看