• python基础知识之装饰器


    一,装饰器(decorator)。(day4.3)

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

    #可以达成的作用# 原则1:不能修改被装饰的函数的源代码。(改源代码有可能会造成未知的错误,因为你不知道有些地方是怎么样调用此函数的)

    #可以达成的作用# 原则2:不能修改被修饰的函数的调用方式。(即,不对原函数照成任何影响)

    1.实现装饰器的知识储备:

    1.函数即”变量“。

    2.高阶函数。

    3.嵌套函数。

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

    ===》》》1.函数即“变量”(要重点理解这个) 

    a).内存存储回收机制(解释器源代码可知其底层实现方式)==》》D4.5.-+11:54

      若没有变量名/函数名也就是说没有地方引用这边内存,在解释器刷新的时候这片内存则会被回收。

    b)函数在内存里的存放机制是:(仅仅写一个函数名则相当于这个函数体所占用的内存地址,而内存地址加上小括号则相当于运行这个内存地址里的”东西“

    可以理解为()就是执行这个它前面的内存地址里的东西的执行动作

    #实例
    #return 后的值是函数运行完成后返回到开始运行处的“东西”
    import time def bar(): time.sleep(0.5) print("in the bar") return 123 print(bar()) t = bar print(bar) t()

    用函数名即def后的为“门牌号”找到一个内存地址再将函数体存入这个内存中。等待使用这个门牌号(即函数名)来调用他对应的内存里的函数体来执行。

     ===》》》2.高阶函数:

      a)把一个函数名当实参传给另一个函数。(可实现,在不修改被装饰的函数的源代码情况下为其添加功能)

       

    #高阶函数的a)功能实例。
    import time
    def bar():
      time.sleep(3)
      print("in the bar")
    def funt1(funt):
      # start_time = time.time()
        print('hello world!')
        return funt
    bar = funt1(bar)
    bar()

      b)返回值中包含函数名。(不修改被修饰的函数的调用方式,对原函数添加了功能。

    import time
    def bar():
        time.sleep(0.5)
        print("in the bar")
    
    # def test2(name):
    #     print(name)
    #     return name
    # print(test2(bar))
    
    def time1(funt):
        start_time = time.time()
        funt()
        end_time = time.time()
        print('该程序运行时间是:%s'%(start_time-end_time))
        return funt
    bar = time1(bar)
    bar() #不修改被修饰的函数的调用方式,对原函数添加了功能。

     ===》》》3.嵌套函数。

    函数里套一个被定义的函数

    #实例
    def test1():
        print("AAA")
        def test2():#嵌套函数只能在这个局部语句块里使用,函数即变量和局部变量同理。
          pass
    #下面的实例可以演示函数的局部性
    def test1():
        x = 'h'
        def test2():
            x = 'h1'
            def test3():
                x ='h2'
                print(x)
            test3()
        test2()
    test1()
    》》》h2
    def test1():
        x = 'h'
        def test2():
            x = 'h1'
            def test3():
                # x ='h2'
                print(x)
            test3()
        test2()
    test1()
    》》》h1
    def test1():
        x = 'h'
        def test2():
            # x = 'h1'
            def test3():
                # x ='h2'
                print(x)
            test3()
        test2()
    test1()
    》》》h

     2.最简单的装饰器实例:

    def timer(func):
        def deco():
            import time
            start_time=time.time()
            func()
            stop_time=time.time()
            print('the func run time is %s'%(start_time-stop_time))
        return deco
    def test():
        import time
        print('start')
        time.sleep(1)
        print('stop')

    test()

    》》》start
       stop

    test=timer(test)

    test()

    》》》start
    stop
    the func run time is -1.0072598457336426

    小节:装饰器是在被装饰的函数头加上@timer即相当于 在使用的时候写了一个test=timer(test)

    def timer(func):
        def deco():
            import time
            start_time=time.time()
            func()
            stop_time=time.time()
            print('the func run time is %s'%(start_time-stop_time))
        return deco
    @timer
    def test():
        import time
        print('start')
        time.sleep(1)
        print('stop')

    test()

    》》》 start
    stop
    the func run time is -1.0072598457336426

    3.装饰器升级,可以修饰随便几个参数的函数,并且可以返回被装饰函数的返回值。

    def timer(func):
        def deco(*args,**kwargs): #修饰随便几个参数的函数
            import time
            start_time=time.time()
            ret=func(*args,**kwargs) #修饰随便几个参数的函数
            stop_time=time.time()
            print('the func run time is %s'%(start_time-stop_time))

      return ret #返回被装饰函数的返回值

        return deco
    @timer
    def test():
        import time
        print('start')
        time.sleep(1)
        print('stop')
    @timer #相当于加了一条test1=timer(test1)
    def test1(name,age):
        print('123',name,age)

    test()
    test1(123,22)  

    4.最终完整版,装饰器。(包含了说明)#51cto博客有相关内容#

    # Author:979
    # blog addr:http://www.cnblogs.com/home979/
    user ="zsw"
    code ="123"
    def auth(aut_type):
        #print(aut_type)#可以了解传入装饰器的aut_type参数是什么量
        def choice(func):
            #print(func)#可以了解传入装饰器的func参数是什么量
            def yanzhen(*args,**kwargs):
                #print(*args,**kwargs)#可以了解传入装饰器的*args,**kwargs参数是什么量
                if aut_type =='local':#这一句是装饰器type:local的具体功能
                    username = input("username:")
                    password = input("password:")
                    if user == username and code == password:
                        print("waiting")
                        # ret = func(*args,**kwargs) #这样的话可以得到func的返回值 并且可以继续运行
                        # return ret #直接用这样一句就可以返回开始得到func的返回值
                        return func(*args,**kwargs) #可用上面两句替换,这一句必须加
                    else:
                        print("Invalid username or password")
                        
                elif aut_type =='ldap':#这一句是装饰器type:ldap的具体功能
                    print("不会弄ldap,搞毛线啊")
            return yanzhen#返回yanzhen的物理地址
        return choice #返回choice的物理地址
    #下面是具体被调用装饰器的函数实例
    def index():
        print("welcom to index")
        
    @auth(aut_type='local')
    def home(bankuai):
        if bankuai =='home':
            print("welcom to home A")
        else:
            print("welcom to home B")
        return "from 123"
    
    @auth(aut_type='ldap')
    def bbs():
        print("welcom to bbs")
    
    index()
    print(home('home'))
    bbs()

    二,匿名函数: 

    没有def申明函数名字。

    例如: 匿名函数

    lambda n:print(n)

    相对于

    def dayin(n):

      print(n)

    这个函数

      

  • 相关阅读:
    list集合对象日期排序
    Mongodb模糊,or,and查询和日期查询
    单例模式
    代理模式
    抽象工厂模式
    java 除数运算获取两位小数
    html5 canvas 使用总结
    @MockBean 注解后 bean成员对象为 null?
    Java8 BiFunction 简单用用
    如何正确安装Ubuntu
  • 原文地址:https://www.cnblogs.com/home979/p/7880651.html
Copyright © 2020-2023  润新知