zoukankan      html  css  js  c++  java
  • python学习笔记-装饰器

    装饰器

    装饰器:本质就是为其他函数添加附加功能
    原则:
    1.不修改被修饰函数的源代码
    2.不修改被修饰函数对调用方式

    装饰器的知识储备
    装饰器=高阶函数+函数嵌套+闭包

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

    例子:函数的参数是一个函数名
    import time
    def foo():
        time.sleep(3)
        print("hello")
    
    def test(func):
    
        #print(func) #内存地址
        start_time=time.time()
        func()
        stop_time=time.time()
        print("函数运行时间是%s"%(stop_time-start_time))
    
    test(foo)

     写一个装饰器

    例子1.多运行了一次,不合格

    import time
    def foo():
        time.sleep(3)
        print("hello")
    
    def timer(func):
        #print(func) #内存地址
        start_time=time.time()
        func()
        stop_time=time.time()
        print("函数运行时间是%s"%(stop_time-start_time))
        return func
    
    foo=timer(foo)
    foo()

    例子:函数嵌套与作用域回顾

    def father(name):
        print("form father %s"%name)
        def son():
            print("my father is %s"%name) #先从本层找name变量,没有就从上一层找
        print(locals()) #显示所有局部变量
        son()
    father("steven")

    装饰器实现

    1、装饰器的架子

    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
    def test():
        time.sleep(3)
        print("test函数运行完毕")
    
    #test=timmer(test) 返回的是wrapper的地址
    test()  #执行的是wrapper()
    
    #@timmer() 就相当于test=timmer(test)

    2、有返回值的情况,获取返回值

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

    3、函数闭包加上参数

    import time
    
    def timmer(func):  
        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
    def test(name,age):
        time.sleep(3)
        print("test函数运行完毕,名称%s,年龄%s"%(name,age))
        return "test函数的返回值"
    
    res=test("张三",18)  #执行的是wrapper()
    print(res)

    4、补充,解压序列

    a,b,c=(1,2,3)     #解压序列
    >>> a,b,c=(1,2,3)
    >>> a
    1
    >>> b
    2
    >>> c
    3
    >>> l=[2,4,2,3,5,7,8,9,5]
    >>> l
    [2, 4, 2, 3, 5, 7, 8, 9, 5]
    >>> a,*_,c=l   # *代表中间所有的,下划线无意义,可以放一个变量名
    >>> a
    2
    >>> c
    5
    >>> a,*d,c=l  
    >>> a
    2
    >>> d    #表示取中间所有的
    [4, 2, 3, 5, 7, 8, 9]
    >>> c
    5
    >>> l
    [2, 4, 2, 3, 5, 7, 8, 9, 5]
    >>> a,b,*_,c,d
    (2, 2, 4, 2, 3, 5, 7, 8, 9, 5, [4, 2, 3, 5, 7, 8, 9])
    >>> b
    2
    View Code
    举例,a=1,b=2。把两个值互换
    #方法一
    >>> a=1
    >>> b=2
    >>> x=a
    >>> a=b
    >>> b=x
    >>> a,b
    (2, 1)
    #方法二
    >>> f1=1
    >>> f2=2
    >>> f1,f2=f2,f1
    >>> f1,f2
    (2, 1)
    View Code

    装饰器应用

    验证功能装饰器
    购物网站举例,略
    user_dic={"username":None,"login":False}
    
    def auth_func(func):
        def wrapper(*args,**kwargs):
            if user_dic["username"] and user_dic["login"]:
                res=func(*args,**kwargs)  
                return res
            username=input("用户名:").strip()
            passwd=input("密码:").strip()
            if username=='job' 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购物车里有笔,手机,电脑"%name)
    
    index()
    home("产品经理")
    shopping_car("产品经理")

    复杂的例子

    #增加了用户

    user_list=[{"name":"steve","passwd":"123"},
               {"name":"mark","passwd":"123"},
               {"name":"jobs","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("用户名或密码错误")
        return wrapper
    
    @auth_func
    def index():
        print("欢迎来到京东主页")
    
    @auth_func
    def home(name):
        print("欢迎你回家%s"%name)
    
    @auth_func
    def shopping_car(name):
        print("%s购物车里有笔,手机,电脑"%name)
    
    index()
    home("产品经理")
    shopping_car("产品经理")

    带参数装饰器

    user_list=[{"name":"steve","passwd":"123"},
               {"name":"mark","passwd":"123"},
               {"name":"jobs","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("ldap认证")
                    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
    def index():
        print("欢迎来到京东主页")
    
    @auth(auth_type='ldap')
    def home(name):
        print("欢迎你回家%s"%name)
    
    @auth(auth_type='haha')
    def shopping_car(name):
        print("%s购物车里有笔,手机,电脑"%name)
    
    index()
    home("产品经理")
    shopping_car("产品经理")


  • 相关阅读:
    layui table中省略号展开,弹框拖动会错位问题
    layui table分页 page为false时,limit问题
    layui 表格在排序之后没有重新渲染问题
    基于jQuery的控件:弹框
    layui layer弹框中表格的显示
    layui select使用问题
    页面强制横屏
    linux下常用命令
    文字超出省略号显示
    Web Notification简单实现桌面消息通知(右下角提示)
  • 原文地址:https://www.cnblogs.com/steven223-z/p/12378577.html
Copyright © 2011-2022 走看看