• Python之路【第七篇】:Python装饰器


    阅读目录

    一、装饰器

    1、装饰器的概念

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

    二、装饰器需要遵循的原则

    #原则:
    1、不修改被修饰函数的源代码
    2、不修改被修饰函数的调用方式
    
    装饰器他人的器具,本事可以是任意可调用对象,被装饰者也可以是任意可调用对象。
    
    #强调装饰器的原则:
    1、不修改被装饰对象的源代码
    2、不修改被装饰对象的调用方式
    
    #装饰器的目标:
    在遵循1和2原则的前提下,为被装饰的对象添加新功能

    三、实现装饰器知识储备

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

    四、高阶函数

    高阶函数的定义:
    1、函数接收的参数是一个函数名
    2、函数的返回值是一个函数名
    3、满足上述条件任意一个,都可称之为高阶函数

    五、函数嵌套

    def father(name):
        print('from father %s' %name)
        def son():
            print('from the son')
            def grandson():
                print('from the grandson')
            grandson()
        son()
    
    father('朱锐')

    六、闭包

    1、闭包

    def father(name):
        print('from father %s' %name)
        def son():
            print('from the son')
            def grandson():
                print('from the grandson')
            grandson()
        son()
    
    father('朱锐')
    
    '''
    闭包
    '''
    
    def father(name):
        def son():
            # name='simon1'
            print('我的爸爸是%s' %name)
            def grandson():
                print('我的爷爷是%s' %name)
            grandson()
        son()
    father('simon')

    2、函数闭包装饰器基本实现

    import time
    def timmer(func):
        def wrapper():
            # print(func)
            start_time=time.time()
            func() #就是在运行test()
            stop_time=time.time()
            print('运行时间是%s' %(stop_time-start_time))
        return wrapper
    @timmer #语法糖,这个是重点
    
    def test():
        time.sleep(3)
        print('test函数运行完毕')
    
    # res=timmer(test) #返回的是wrapper的地址
    # res() #执行的是wrapper()
    
    # test=timmer(test) #返回的是wrapper的地址
    # test() #执行的是wrapper()
    
    test()
    '''
    语法糖
    '''
    # @timmer #就相当于 test=timmer(test)

    3、函数闭包加上返回值

    #未加返回值
    import time
    def timmer(func):
        def wrapper():
            # print(func)
            start_time=time.time()
            func() #就是在运行test()
            stop_time=time.time()
            print('运行时间是%s' %(stop_time-start_time))
            return 123
        return wrapper
    @timmer #语法糖
    
    def test():
        time.sleep(3)
        print('test函数运行完毕')
        return '这是test的返回值'
    res=test() #就是在运行wrapper
    print(res)
    
    运行结果如下:
    C:Python35python3.exe G:/python_s3/day20/加上返回值.py
    test函数运行完毕
    运行时间是3.000171661376953
    123
    #加上返回值
    import time
    def timmer(func):
        def wrapper():
            # print(func)
            start_time=time.time()
            res=func() #就是在运行test()     ##主要修改这里1
            stop_time=time.time()
            print('运行时间是%s' %(stop_time-start_time))
            return res     ##修改这里2
        return wrapper
    @timmer #语法糖
    
    def test():
        time.sleep(3)
        print('test函数运行完毕')
        return '这是test的返回值'
    res=test() #就是在运行wrapper
    print(res)
    
    运行结果如下:
    C:Python35python3.exe G:/python_s3/day20/加上返回值.py
    test函数运行完毕
    运行时间是3.000171661376953
    这是test的返回值

    4、函数闭包加上参数

    import time
    def timmer(func):
        def wrapper(name,age):   #加入参数,name,age
            # print(func)
            start_time=time.time()
            res=func(name,age) ##加入参数,name,age
            stop_time=time.time()
            print('运行时间是%s' %(stop_time-start_time))
            return res
        return wrapper
    @timmer #语法糖
    
    def test(name,age): #加入参数,name,age
        time.sleep(3)
        print('test函数运行完毕,名字是【%s】,年龄是【%s】' % (name,age))
        return '这是test的返回值'
    res=test('simon',18) #就是在运行wrapper
    print(res)

    使用可变长参数代码如下:达到的效果是传参灵活

    import time
    def timmer(func):
        def wrapper(*args,**kwargs): #test('simon',18)  args=('simon') kwargs={'age':18}
            # print(func)
            start_time=time.time()
            res=func(*args,**kwargs) #就是在运行test()     func(*('simon'),**{'age':18})
            stop_time=time.time()
            print('运行时间是%s' %(stop_time-start_time))
            return res
        return wrapper
    @timmer #语法糖
    
    def test(name,age):
        time.sleep(3)
        print('test函数运行完毕,名字是【%s】,年龄是【%s】' % (name,age))
        return '这是test的返回值'
    def test1(name,age,gender):
        time.sleep(1)
        print('test函数运行完毕,名字是【%s】,年龄是【%s】,性别是【%s】' % (name,age,gender))
    res=test('simon',18) #就是在运行wrapper
    print(res)
    
    test1('simon',18,'male')

    5、装饰器的使用

    #无参装饰器
    import time
    def timmer(func):
        def wrapper(*args,**kwargs):
            start_time=time.time()
            res=func(*args,**kwargs)
            stop_time=time.time()
            print('run time is %s' %(stop_time-start_time))
            return res
        return wrapper
    
    @timmer
    def foo():
        time.sleep(3)
        print('from foo')
    foo()
    #有参装饰器
    def auth(driver='file'):
        def auth2(func):
            def wrapper(*args,**kwargs):
                name=input("user: ")
                pwd=input("pwd: ")
    
                if driver == 'file':
                    if name == 'simon' and pwd == '123':
                        print('login successful')
                        res=func(*args,**kwargs)
                        return res
                elif driver == 'ldap':
                    print('ldap')
            return wrapper
        return auth2
    
    @auth(driver='file')
    def foo(name):
        print(name)
    
    foo('simon')

     #验证功能装饰器

    #验证功能装饰器
    user_list=[
        {'name':'simon','passwd':'123'},
        {'name':'zhurui','passwd':'123'},
        {'name':'william','passwd':'123'},
        {'name':'zhurui1','passwd':'123'},
    ]
    current_dic={'username':None,'login':False}
    
    
    def auth_func(func):
        def wrapper(*args,**kwargs):
            if current_dic['username'] and current_dic['login']:
                res=func(*args,**kwargs)
                return res
            username=input('用户名:').strip()
            passwd=input('密码:').strip()
            for user_dic in user_list:
                if username == user_dic['name'] and passwd == user_dic['passwd']:
                    current_dic['username']=username
                    current_dic['login']=True
                    res=func(*args,**kwargs)
                    return res
            else:
                print('用户名或者密码错误')
    
            # if username == 'simon' and passwd == '123':
            #     user_dic['username']=username
            #     user_dic['login']=True
            #     res=func(*args,**kwargs)
            #     return res
            # else:
            #     print('用户名或密码错误')
        return wrapper
    
    @auth_func
    def index():
        print('欢迎来到某宝首页')
    @auth_func
    def home(name):
        print('欢迎回家%s' %name)
    @auth_func
    def shopping_car(name):
        print('%s购物车里有[%s,%s,%s]' %(name,'餐具','沙发','电动车'))
    
    print('before----->',current_dic)
    index()
    print('after---->',current_dic)
    home('simon')
    # shopping_car('simon')

    #带参数验证功能装饰器

    #带参数验证功能装饰器
    user_list=[
        {'name':'simon','passwd':'123'},
        {'name':'zhurui','passwd':'123'},
        {'name':'william','passwd':'123'},
        {'name':'zhurui1','passwd':'123'},
    ]
    current_dic={'username':None,'login':False}
    
    def auth(auth_type='filedb'):
        def auth_func(func):
            def wrapper(*args,**kwargs):
                print('认证类型是',auth_type)
                if auth_type == 'filedb':
                    if current_dic['username'] and current_dic['login']:
                        res = func(*args, **kwargs)
                        return res
                    username=input('用户名:').strip()
                    passwd=input('密码:').strip()
                    for user_dic in user_list:
                        if username == user_dic['name'] and passwd == user_dic['passwd']:
                            current_dic['username']=username
                            current_dic['login']=True
                            res = func(*args, **kwargs)
                            return res
                    else:
                        print('用户名或者密码错误')
                elif auth_type == 'ldap':
                    print('这玩意没搞过,不知道怎么玩')
                    res = func(*args, **kwargs)
                    return res
                else:
                    print('鬼才知道你用的什么认证方式')
                    res = func(*args, **kwargs)
                    return res
    
            return wrapper
        return auth_func
    
    @auth(auth_type='filedb') #auth_func=auth(auth_type='filedb')-->@auth_func 附加了一个auth_type  --->index=auth_func(index)
    def index():
        print('欢迎来到某宝主页')
    
    @auth(auth_type='ldap')
    def home(name):
        print('欢迎回家%s' %name)
    #
    @auth(auth_type='sssssss')
    def shopping_car(name):
        print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))
    
    # print('before-->',current_dic)
    # index()
    # print('after--->',current_dic)
    # home('simon')
    shopping_car('simon')
  • 相关阅读:
    sort uniq 命令 企业应用场景实战排序
    网络管理相关命令常用必回基础实战
    Zabbix 3.0入门到企业实战(自带模板介绍)
    jsp页面指令
    jsp九大内置对象
    如何将静态页面转化为动态页面
    转发与重定向区别
    cookie的保存时间
    登陆界面 实现思路
    卸载了mysql之后,mysql服务仍在,显示读取描述失败,错误代码2
  • 原文地址:https://www.cnblogs.com/hackerer/p/10727349.html
Copyright © 2020-2023  润新知