• Python 基础 装饰器


        今天把学过的装饰器的知识进行回顾一下,说到装饰器,第一反应就是这个东西呢就是用来装逼的,为啥这样说呢,是应为没有这个东西照样可以干活,大部分工作都是可以做的,不管咋样还是把学过的装逼器梳理一下吧。

        一、装饰器是个什么鬼?

            装饰的意思呢,就是修饰,装点的意思可以给别的函数添加新的功能,器呢就是函数的意思,so 装饰器即是为别的函数添加新的功能的函数。

        二、作为一个装饰器,他、它有什么样的规则呢?  

            1.不修改被装饰函数的源代码(开放封闭原则

            2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式

        三、如何实现一个装饰器呢?

            要实现一个可以使用的装饰器就需要满足:装饰器=高阶函数+函数嵌套+闭包

        四、高阶函数

            上节介绍完了什么是高阶函数,只要满足:1.函数可以接受函数名当参数进行传递 2.函数的返回值可以返回一个函数名  只要能够满足上面的任何一条就认为构成的这个函数是高阶函数

            高阶函数的例子:

    def foo():
        print('我的函数名作为参数传给高阶函数')
    def gao_jie1(func):
        print('我就是高阶函数1,我接收的参数名是%s' %func)
        func()
    
    def gao_jie2(func):
        print('我就是高阶函数2,我的返回值是%s' %func)
        return func
    
    gao_jie1(foo)
    gao_jie2(foo)
    输出的结果是:
    我就是高阶函数1,我接收的参数名是<function foo at 0x006896A8>
    我的函数名作为参数传给高阶函数
    我就是高阶函数2,我的返回值是<function foo at 0x006896A8>
    #高阶函数应用1:把函数当做参数传给高阶函数
    import time
    def foo():
        print('from the foo')
    
    def timmer(func):
        start_time=time.time()
        func()
        stop_time=time.time()
        print('函数%s 运行时间是%s' %(func,stop_time-start_time))
    timmer(foo)
    #总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式
    
    把函数当做参数传给高阶函数
    #高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
    import time
    def foo():
        print('from the foo')
    
    def timmer(func):
        start_time=time.time()
        return func
        stop_time=time.time()
        print('函数%s 运行时间是%s' %(func,stop_time-start_time))
    foo=timmer(foo)
    foo()
    #总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能
    
    函数返回值是函数名

    五、函数嵌套(就是函数中还有定义函数)

    def father(name):
        print('from father %s' %name)
        def son():
            print('from son')
            def grandson():
                print('from grandson')
            grandson()
        son()
    
    father('还是牛')

    六、闭包:(在一个作用域中放入的定义变量,就像打了一个包)

    #闭包的概念:闭就是封装的意思,就是把变量分装起来;包:就是层的意思,与之前作用域意思是一样的。
    #grandson中的变量有name(形式参数);son中的变量有grandson(函数名也是变量);father中的变量有:name(形式参数) son
    def father(name):
        print('from the father %s' %(name))
        def son():
            print('from the son')
            def grandson():
                print('from the grandson %s'%(name))
            grandson()
        son()
    
    father('SB')

    七、装饰器的基本框架

    def timmer(func):
        def wrapper():
            print(func)
            func()
        return wrapper
    
    def boo():
        print('你就是个傻逼!')
    
    
    res = timmer(boo) # 返回的是wrapper的内存地址 <function timmer.<locals>.wrapper at 0x02129420>
    #print(res)
    res() #是在执行wrapper 函数

    八、装饰器的两种形式:

    第一种 无参数的装饰器

    user_list=[
        {'name':'alex','passwd':'123'},
        {'name':'linhaifeng','passwd':'123'},
        {'name':'wupeiqi','passwd':'123'},
        {'name':'yuanhao','passwd':'123'},
    ]
    
    current_user={'username':None,'login':False}
    
    def auth_deco(func):
        def wrapper(*args,**kwargs):
            if current_user['username'] and current_user['login']:
                res=func(*args,**kwargs)
                return res
            username=input('用户名: ').strip()
            passwd=input('密码: ').strip()
    
            for index,user_dic in enumerate(user_list):
                if username == user_dic['name'] and passwd == user_dic['passwd']:
                    current_user['username']=username
    
                    current_user['login']=True
                    res=func(*args,**kwargs)
                    return res
                    break
            else:
                print('用户名或者密码错误,重新登录')
    
        return wrapper
    
    @auth_deco
    def index():
        print('欢迎来到主页面')
    
    @auth_deco
    def home():
        print('这里是你家')
    
    def shopping_car():
        print('查看购物车啊亲')
    
    def order():
        print('查看订单啊亲')
    
    print(user_list)
    # index()
    print(user_list)
    home()
    

    第二种 含有参数的装饰器

    user_list=[
        {'name':'alex','passwd':'123'},
        {'name':'linhaifeng','passwd':'123'},
        {'name':'wupeiqi','passwd':'123'},
        {'name':'yuanhao','passwd':'123'},
    ]
    
    current_user={'username':None,'login':False}
    def auth(auth_type='file'):
        def auth_deco(func):
            def wrapper(*args,**kwargs):
                if auth_type == 'file':
                    if current_user['username'] and current_user['login']:
                        res=func(*args,**kwargs)
                        return res
                    username=input('用户名: ').strip()
                    passwd=input('密码: ').strip()
    
                    for index,user_dic in enumerate(user_list):
                        if username == user_dic['name'] and passwd == user_dic['passwd']:
                            current_user['username']=username
                            current_user['login']=True
                            res=func(*args,**kwargs)
                            return res
                            break
                    else:
                        print('用户名或者密码错误,重新登录')
                elif auth_type == 'ldap':
                    print('巴拉巴拉小魔仙')
                    res=func(*args,**kwargs)
                    return res
            return wrapper
        return auth_deco
    
    
    #auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file')
    #就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数
    @auth(auth_type='ldap')
    def index():
        print('欢迎来到主页面')
    
    @auth(auth_type='ldap')
    def home():
        print('这里是你家')
    
    def shopping_car():
        print('查看购物车啊亲')
    
    def order():
        print('查看订单啊亲')
    
    # print(user_list)
    index()
    # print(user_list)
    home()
    

     

           

  • 相关阅读:
    MyBatis的初始化方式
    WCF X.509验证
    NPOI导出EXCEL 打印设置分页及打印标题
    一些旁门左道
    曲线救国:IIS7集成模式下如何获取网站的URL
    图片的粘贴上传
    让EF飞一会儿:如何用Entity Framework 6 连接Sqlite数据库
    ASP.NET 保存txt文件
    JavaScript高级程序设计学习笔记--高级技巧
    JavaScript高级程序设计学习笔记--错误处理与调试
  • 原文地址:https://www.cnblogs.com/haishiniu123/p/6774511.html
Copyright © 2020-2023  润新知