zoukankan      html  css  js  c++  java
  • 装饰器

    1. 什么叫装饰器

      装饰器本质就是函数,为其他函数添加附加功能

      原则:

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

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

     

    2. 装饰器的知识储备:

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

    3. 高阶函数

      高阶函数定义:

      1)函数接收的参数是一个函数名

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

      3)满足上述条件中的任意一个,都可称之为高阶函数

    def mvp(func):             #高阶函数1,接收的参数是一个函数名        
        res = func()
        return res
    
    def dpoy():                  #高阶函数2,函数的返回值是一个函数名
        print('mvp和dpoy都属于lebron')
        return fmvp
    
    def fmvp():
        print('当然fmvp也属于lebron')

      高阶函数(把函数当做参数传给高阶函数)的应用1:计算函数运行的时间

    import time
    def timmer(func):
        start_time = time.time()
        func()
        stop_time = time.time()
        print('函数的运行时间为%s' %(stop_time - start_time))
    
    def test():
        time.sleep(2)
        print('来自函数test')
    
    timmer(test)

    #总结:我们确实为函数test增加了test运行时间的功能,但是test原来的执行方式是test(),现在我们需要调用高阶函数timmer(test),改变了函数的调用方式

      高阶函数(函数的返回值是一个函数名)的应用2:

    import time
    def timmer(func):
        start_time = time.time()
        func()
        stop_time = time.time()
        print('函数的运行时间为%s' %(stop_time - start_time))
        return func
    
    def test():
        time.sleep(2)
        print('来自函数test')
    
    test = timmer(test)
    test()
    
    
    #总结:我们为函数test增加了test运行时间的功能,也没有改变test函数的执行方式和源代码,但是这种方法使得test函数运行了两次,相当于没有为foo增加任何新功能

      高阶函数总结
      1.函数接收的参数是一个函数名
      作用:在不修改函数源代码的前提下,为函数添加新功能,
      不足:会改变函数的调用方式
      2.函数的返回值是一个函数名
      作用:不修改函数的调用方式
      不足:不能添加新功能

     

    4. 函数嵌套

    def father(name1):
        print('爸爸是%s' %name1)
    
        def son(name2):
            print('儿子是%s' %name2)
    
            def grandson(name3):
                print('孙子是%s' %name3)
            grandson('bose')
        son('xueba')
    
    father('sword')

    5. 闭包

      闭包:在一个作用域里放入定义变量,相当于打了一个包。其实就是对作用域的一种说法,在函数嵌套中,因为作用域的不同,内一层的变量不能在外一层使用,就相当于给内一层的变量封包

    def father(name):
        print('爸爸是%s' %name)
    
        def son():
            name = 'xueba'
            print('儿子是%s' %name)
            def grandson():
                name = 'bose'
                print('孙子是%s' %name)
            grandson()
        son()
    
    father('sword')

    6. 无参装饰器

      无参装饰器=高级函数+函数嵌套

      基本框架

    def timmer(func):
         def wrapper():  
             res = func()
        return wrapper    

     

      加上参数

    def timmer(func):
        def wrapper(*args, **kwargs):
            func(*args, **kwargs)
        return wrapper

     

      加上功能

    import time
    
    def timmer(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            func()
            stop_time = time.time()
            print('函数%s,运行时间%s' %(func, stop_time - start_time)
        return wrapper

      加上返回值

    import time
     8
    de3f timmer(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            res = func()
            stop_time = time.time()
            print('函数%s,运行时间%s' %(func, stop_time - start_time)
            return res
        return wrapper

     

       使用装饰器

    import time
    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
    
    def test():
        time.sleep(2)
        print('来自函数test')
    
    test = timmer(test)
    test()

      语法糖@

    import time
    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     #相当于test = timmer(test)
    def test():
        time.sleep(2)
        print('来自函数test')
    
    # test = timmer(test)
    test()

    7. 装饰器应用示例

    user_list = [
        {'name': 'chen', 'passwd': '123'},
        {'name': 'lebron', 'passwd': '123'},
        {'name': 'druant', 'passwd': '123'},
        {'name': 'curry', 'passwd': '123'}
                 ]
    user_dic = {'name': None, 'login': False}
    
    def passwd(func):
        def wrapper(*args, **kwargs):
            if user_dic['name'] and user_dic['login']:
                res = func(*args, **kwargs)
                return res
            name = input('用户名:')
            password = input('密码:')
            for index, user_id in enumerate(user_list):
                if name == user_id['name'] and password == user_id['passwd']:
                    user_dic['name'] = name
                    user_dic['login'] = True
                    res = func(*args, **kwargs)
                    return res
            else:
                print('用户名或者密码错误')
        return wrapper
    
    @passwd
    def home():
        print('欢迎登陆')
    
    @passwd
    def ordr():
        print('所有订单')
    
    @passwd
    def shopcar():
        print('购物车')
    
    home()

     

     

    user_list = [
        {'name': 'chen', 'passwd': '123'},
        {'name': 'lebron', 'passwd': '123'},
        {'name': 'druant', 'passwd': '123'},
        {'name': 'curry', 'passwd': '123'}
                 ]
    user_dic = {'name': None, 'login': False}
    
    def passwd(passwd_tpye = 'file'):
        def passwd_deo(func):
            def wrapper(*args, **kwargs):
                if passwd_tpye == 'file':
                    if user_dic['name'] and user_dic['login']:
                        res = func(*args, **kwargs)
                        return res
                    name = input('用户名:')
                    password = input('密码:')
                    for index, user_id in enumerate(user_list):
                        if name == user_id['name'] and password == user_id['passwd']:
                            user_dic['name'] = name
                            user_dic['login'] = True
                            res = func(*args, **kwargs)
                            return res
                    else:
                        print('用户名或者密码错误')
                elif passwd_tpye == 'ldap':
                    print('下次再处理')
                    res = func(*args, **kwargs)
                    return res
            return wrapper
        return passwd_deo
    @passwd(passwd_tpye = 'file')     
    def home():
        print('欢迎登陆')
    
    @passwd(passwd_tpye = 'ldap')
    def ordr():
        print('所有订单')
    
    @passwd(passwd_tpye = 'file')
    def shopcar():
        print('购物车')
    
    
    home()
    ordr()

    #passwd(passwd_type='file')就是在运行一个函数,然后返回passwd_deco,所以@passwd(passwd_type='file')
    就相当于@passwd_deco,只不过现在,我们的passwd_deco作为一个闭包的应用,外层的包passwd给它留了一个passwd_type='file'参数
     

        

  • 相关阅读:
    Nginx日志定时切割脚本
    阿里大于短信接口
    阿里云Linux系统挂载数据盘
    阿里云 OSS+CDN
    值得一学的几条谷歌搜索技巧
    【转】makefile语法规则
    【转】GCC使用简介
    网络编程中常见地址结构与转换(IPv4/IPv6)
    【转】adns解析库——域名解析实例(C++、linux)
    【转】什么是自动化测试
  • 原文地址:https://www.cnblogs.com/cjsword/p/10482011.html
Copyright © 2011-2022 走看看