zoukankan      html  css  js  c++  java
  • 12.Python(装饰器)

    一、定义

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

    原则:

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

    2、不修改被修饰函数的调用方式

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

    二、高阶函数

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

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

    3.满足上述其中一个条件就是高阶函数

    下例中是一个高阶函数:

    def foo():
        print("你好")
    
    def test(func):#是一个高阶函数
        print(func)#func有了foo的内存地址
        func()#运行foo函数
    test(foo)

    def foo():
        print("来自foo")
    
    def test(func):#接收参数是函数名
        func()
        return func#返回值还是函数名
    foo=test(foo)
    foo()#还是执行原来函数的调用方式

     三、装饰器实现

    1、基本实现

    import time
    
    def timmer(func): #func=test
        def wrapper():
            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()  #执行的是wrapper()

     2、原本的函数有返回值

    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()  
    print(res)

     3、加上参数

    import time
    def timmer(func): #func=test1
        def wrapper(*args, **kwargs): #固定用法,不管原函数有几个参数,这种形式都能接收
            start_time = time.time()
            res = func(*args, **kwargs) #就是在运行test1()  func(*('alex'),**{'age':18;'gender':male;....})
            stop_time = time.time()
            print('运行时间是%s' % (stop_time-start_time))
            return res
        return wrapper
    
    @timmer
    def test1(name, age, gender, habit):
        time.sleep(1)
        print('test1函数运行完毕,名字是【%s】 年龄是【%s】 ,性别是【%s】,爱好是【%s】' %(name, age, gender, habit))
        return '这是test的返回值'
    
    test1('alex',18,'male',"")

    4、验证功能

    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_func(func):
        def wrapper(*args, **kwargs):
            if current_dic['username'] and current_dic['login']:#有人开始登录,没人登录的话就直接不往下运行了
                return 0
            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:#for也可以加else,说明for循环中没有匹配的
                    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('产品经理')

     5、带参数验证功能装饰器

    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']:
                        return 0
                    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') 
    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,'奶茶','妹妹','娃娃'))
    
    
    index()
    home('产品经理')
    shopping_car('产品经理')
  • 相关阅读:
    Cordova+angularjs+ionic+vs2015开发(四)
    Cordova+angularjs+ionic+vs2015开发(三)
    Cordova+angularjs+ionic+vs2015开发(二)
    Cordova+angularjs+ionic+vs2015开发(一)
    VS2015+AngularJS+Ionic开发
    angularjs开发总结
    ionic+cordova+angularJs监听刷新
    VIN码识别/车架号OCR识别:快速占领汽车后市场数据入口
    说一说VIN码识别,车架号识别那些事
    汽车VIN码,车架号,移动端,服务器端OCR识别 技术公司
  • 原文地址:https://www.cnblogs.com/zhaojiayu/p/13797845.html
Copyright © 2011-2022 走看看