zoukankan      html  css  js  c++  java
  • Python基础(六)-装饰器

    一、高阶函数

    1.1、高阶函数的定义

    • 函数接受的是一个函数名
    • 函数的返回值是一个函数名
    • 满足上述条件的任意一个,都可以被称之为高阶函数
    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.2、高阶函数的应用

    1)将函数名传递给高阶函数

    import time
    def foo():
        time.sleep(3)
        print('你好')
    
    def test(func):
        # print(func)
        start_time=time.time()
        func()
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
    
    test(foo)
    
    你好
    函数运行时间是  3.0009939670562744
    
    #我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数test(foo),改变了函数的调用方式

    2)高阶函数返回的是一个函数名

    #没有改变函数的调用方式,但多运行了一次,不合格
    import time
    def foo():
        time.sleep(3)
        print('你好')
    
    def test(func):
        # print(func)
        start_time=time.time()
        func()
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
        return func
    
    foo = test(foo)   #此时已经调用了foo,下面又调用了一次
    foo()
    
    你好
    函数运行时间是  3.000460386276245
    你好

    3)没有修改被修饰函数的源代码,也没有修改被修饰函数的调用方式,但是也没有为被修饰函数添加新功能

    import time
    def foo():
        time.sleep(3)
        print('来自foo')
    
    def timer(func):
        start_time=time.time()
        return func
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
    
    foo=timer(foo)
    foo()
    
    来自foo

    1.3、高阶函数总结

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

      作用:在不修改函数源代码的前提下,为函数添加新功能,

      不足:会改变函数的调用方式

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

      作用:不修改函数的调用方式

      不足:不能添加新功能

    二、函数的嵌套

    2.1、函数嵌套定义

    def father(name):
        print('from father %s' %name)
        def son():
            print('from son')
            def grandson():
                print('from grandson')
            grandson()
        son()
    
    father('AAA')

    2.2、闭包

    def father(auth_type):
        # print('from father %s' %name)
        def son():
            # name='linhaifeng_1'
            # print('我的爸爸是%s' %name)
            def grandson():
                print('我的爷爷是%s' %auth_type)
            grandson()
        # print(locals())
        son()
    # father('A')
    father('filedb')
    
    #我的爷爷是filedb

    三、装饰器简介

    本质上是函数,功能是为其他han书添加新功能

    3.1、装饰器遵循的原则

    • 不修改被装饰函数的源代码(开放封闭原则)
    • 为被装饰的添加新功能后,不修改被装饰函数的调用方式

    3.2、实现装饰器的知识储备

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

    3.3、装饰器的基本实现

    import time
    def timmer(func): #func=test
        def wrapper():
            # print(func)
            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()
    
    # res=timmer(test)  #返回的是wrapper的地址
    # res()  #执行的是wrapper()
    
    # test=timmer(test)  #返回的是wrapper的地址
    # test()  #执行的是wrapper()
    
    #  @timmer  就相当于 test=timmer(test)

    3.4、函数添加返回值

    import time
    def timmer(func): #func=test
        def wrapper():
            start_time=time.time()
            res=func() #就是在运行test()
            stop_time = time.time()
            print('运行时间是%s' %(stop_time-start_time))
            return res
        return wrapper
    
    @timmer #test=timmer(test)
    def test():
        time.sleep(3)
        print('test函数运行完毕')
        return '这是test的返回值'
    
    res=test()  #就是在运行wrapper
    print(res)
    
    运行时间是3.000176191329956
    这是test的返回值

    3.5、函数添加参数

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

    3.6、装饰的应用

    user_list=[
        {'name':'alex','passwd':'123'},
        {'name':'linhaifeng','passwd':'123'},
        {'name':'wupeiqi','passwd':'123'},
        {'name':'yuanhao','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('产品经理')
    shopping_car('产品经理')
  • 相关阅读:
    做一天业务员的感觉:辛苦!
    我的乒乓生涯之三浑浑噩噩的中学六年
    名菊照片(二)
    今天,同事的裤子破了
    昨晚,再一次兵败滑铁卢
    今天去世纪公园看名菊展,拍了好多照片发上来大家一起欣赏:)
    寻找上海市乒友喜欢打乒乓的朋友都进来看看
    同学给我两张f1照片:)
    又搞到几张f1照片,发上来给大家养眼
    我的乒乓生涯之四乒乓姻缘
  • 原文地址:https://www.cnblogs.com/hujinzhong/p/11470878.html
Copyright © 2011-2022 走看看