• python学习DAY9(装饰器)


    装饰器:
    1.本质:是函数 (装饰其他函数)为其他函数添加附加功能
    2.原则:(1)不能修改被装饰的函数的源代码(不能需要增加功能的函数的源代码)
            (2)不能修改被装饰的函数的调用方式
            
    
    实现装饰器的相关知识:
    1.函数即“变量”(即把函数体赋值给函数名)
    2.高阶函数(A把一个函数名当做实参传给另外一个函数(不修改被装饰函数的源代码的情况下)、B返回值中包含函数名)
    {A:实现新功能不修改源代码
    import time
    def test(func):
        start_time=time.time()
        func()                          #相当于运行bar()----------高阶函数的运用
        stop_time=time.time()
        print("fun time %s" %(stop_time-start_time))
    def bar():
        time.sleep(3)
        print("bar")
    test(bar)             #func=bar 传递的是一个内存地址  不能传bar(),因为传的只是函数体,不是内存地址
    #-----------------------------------------------------------------
    B:实现新功能不修改源代码且调用方式相同
    import time
    def bar():
        time.sleep(3)
        print("bar")
    def test(func):
        print(func)
        return func          #返回一个内存地址,使调用方式能和原来相同相同
    bar=test(bar)
    bar()                    #做到了不修改源代码且调用方式依然相同的高阶函数(新的覆盖旧的)3.嵌套函数
    def boo():
        print("in the boo")
        def too():
            print("in the too")
        too()
    boo()
    
    
    #-------------------------------------
    高阶函数+嵌套函数=装饰器
    #-------**********为test1和test2分别加上统计运行时间的功能(装饰器实现)***********------
    # Author:barry allen
    # -*- coding:utf-8 -*-
    import time
    def timer(func):
        def deco():
            start_time=time.time()
            func()
            stop_time=time.time()
            print("fun time is %s"%(stop_time-start_time))
        return deco
    @timer                         #相当于test1=timer(test1)
    def test1():
        time.sleep(3)
        print("in the test1")
    @timer
    def test2():
        time.sleep(3)
        print("in the test2")
    test1()
    test2()
    #如test1(),先走装饰器定义,然后转到被装饰的函数,func获取该函数的地址空间,等到调用test1()的时候再走装饰器新增的功能定义(即走deco())
    
    
    
    
    
    #*---------------------------不确定参数的装饰器
    # Author:barry allen
    # -*- coding:utf-8 -*-
    import time
    def timer(func):
        def deco(*args,**kwargs):                     #调用时没有传进参数,则为空,如果有传参数,则匹配对应的参数
            start_time=time.time()
            func(*args,**kwargs)
            stop_time=time.time()
            print("fun time is %s"%(stop_time-start_time))
        return deco
    @timer
    def test1(name,age):
        time.sleep(3)
        print("test1",name,age)
    # @timer
    # def test2():
    #     time.sleep(3)
    #     print("in the test2")
    test1("",12)
    # test2()
    
    
    
    
    
    
    
    #---------装饰器简单应用------------
    # -*-coding:utf-8 -*-
    user,passwd='lin','123'
    def auth(func):
        def wrapper(*args,**kwargs):
            username = input("username:").strip()
            password= input("password").strip()
            if user==username and passwd==password:
                print("33[32;1muser has passed 33[0m")
                func(*args,**kwargs)
                '''res=func(*args,**kwargs)
                   return res 
                   如果源代码修改且有返回结果输出,此时在装饰器要这样写法才不会丢失有返回结果的新源代码函数
                '''
            else:
                exit("33[31;1mfailed 33[0m")
        return wrapper
    
    def index():
        print( "welcome to the index page")
    @auth
    def home():
        print("welcome to the home page")
        #return "from home"         接上个注释说明
    @auth
    def bbs():
        print("welcome to the bbs page")
    index()
    home()
    #print(home())
    bbs()
    
    
    
    
    
    
    
    
    
    
    
    
    #-----------进阶应用
    #装饰器可以定义不同的类型传进装饰器的参数,并在装饰器里面根据条件判断
    __author__ = "Alex Li"
    import time
    user,passwd = 'alex','abc123'
    def auth(auth_type):
        print("auth func:",auth_type)
        def outer_wrapper(func):
            def wrapper(*args, **kwargs):
                print("wrapper func args:", *args, **kwargs)
                if auth_type == "local":
                    username = input("Username:").strip()
                    password = input("Password:").strip()
                    if user == username and passwd == password:
                        print("33[32;1mUser has passed authentication33[0m")
                        res = func(*args, **kwargs)  # from home
                        print("---after authenticaion ")
                        return res
                    else:
                        exit("33[31;1mInvalid username or password33[0m")
                elif auth_type == "ldap":
                    print("ldap......")
    
            return wrapper
        return outer_wrapper
    
    def index():
        print("welcome to index page")
    @auth(auth_type="local") # home = wrapper()
    def home():
        print("welcome to home  page")
        return "from home"
    
    @auth(auth_type="ldap")
    def bbs():
        print("welcome to bbs  page")
    
    index()
    print(home()) #wrapper()
    bbs()
  • 相关阅读:
    可实现B站 蒙版弹幕 效果的前端组件 —— Barrage UI
    C# 中的"yield"使用
    不遮挡人物弹幕是怎么实现的——图片蒙版效果-webkit-mask
    使用eslint检查代码质量
    vue 项目中assets 和static的区别
    快速生成html文本文档——typora
    VsCode中好用的git源代码管理插件GitLens
    C# 根据前台校验的值,决定是否执行后台方法
    C# 从字符串中取出英文字母
    C# 科学计数法转换成数字
  • 原文地址:https://www.cnblogs.com/god-for-speed/p/11167269.html
Copyright © 2020-2023  润新知