• Python基础(九)-装饰器


    什么是装饰器

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

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

    装饰器原则

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

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

    高阶函数

    高阶函数定义:
    1.函数接收的参数是一个函数名

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

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

    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:把函数当做参数传给高阶函数
    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增加任何新功能
    函数返回值是函数名

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

    函数嵌套

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

    闭包

    '''
    闭包:在一个作用域里放入定义变量,相当于打了一个包
    '''
    def father(name):
        def son():
            # name='alex'
            print('我爸爸是 [%s]' %name)
            def grandson():
                # name='wupeiqi'
                print('我爷爷是 [%s]' %name)
            grandson()
        son()
    
    father('fuck')

    无参装饰器

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

    基本框架:

    def timer(func):
        def wrapper():
            func()
        return wrapper

    带参:

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

    加功能:

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

    加返回值:

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

    使用装饰器

    def cal(array):
        res=0
        for i in array:
            res+=i
        return res
    
    cal=timer(cal)
    cal(range(10))

    语法糖@

    @timer  #@timer就等同于cal=timer(cal)
    def cal(array):
        res=0
        for i in array:
            res+=i
        return res
    
    cal(range(10))

    装饰器事例

    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()
    带参装饰器

     

  • 相关阅读:
    Oracle -- Create Tablespace
    EntityFramework-DBFirst-重新生成后写的验证消失(解决办法)
    UILocalNotification本地通知
    属性观察者willSet与didSet
    常用后台frame框架
    Windows常用CMD命令
    常用的格式符与转义字符
    Windows操作系统常用快捷键
    Mac操作系统常用快捷键
    srp render queue 失效
  • 原文地址:https://www.cnblogs.com/chenzhuo-/p/6148489.html
Copyright © 2020-2023  润新知