zoukankan      html  css  js  c++  java
  • 装饰器函数

    装饰器函数

    什么是装饰器函数?

      装饰器函数的本质就是闭包函数,也就是函数嵌套,内部函数调用外层函数变量

    装饰器函数的功能

      在不修改原函数以及调用方式的情况下,对原函数的功能进行扩展.

    def warpper(func):
        def inner():
            ret = func()
            return ret
        return inner
    
    @warpper  #这里func1 = warpper(func1)  也就是inner()
    def func1()
        print('is ok!')
    func1()
    
    #被装饰器修饰过的函数在执行的步骤:
        1.执行func1()的时候先执行warpper函数,同时将下面func1函数作为参数赋值func1()
        2.这时warpper函数走完返回inner,inner=赋值后func1
        3.func1() ==inner()调用内存函数
        4.这时候走内存inner函数,内部调用下面func1()打印出 is ok
    简单的装饰器函数

    为什么要有装饰器函数?

      因为我们在日常开发的过程中,不可能一次性将所有的应用功能全部实现,就算实现了以后也肯定会修改,所以我们必须允许代码可扩展,添加新功能,而装饰器函数恰好能够解决这一问题.在这种背景下,装饰器函数应用能够极大提高开发效率.

    继续探索带参数的装饰器函数

    import time
    
    def timer(func):
    
        def inner(num):
            start = time.time()
            func(num)
            print(time.time()-start)
        return inner
    
    @timer
    def func(num):
        print(num)
    
    func(1010)
    
    #输出 : 1010
                0.0
    简单的带参数的装饰器函数

    通过查看上面代码发现装饰器函数没有返回值,没有返回值的函数可是缺乏灵魂的呢!

    带参数有返回值的装饰器函数

    #一个装饰器装饰多个函数
    def warpper(func):
    def inner(*args,**kwargs):
    print('nice')
    ret = func(*args,**kwargs)
    print('bad')
    return ret
    return inner

    @warpper
    def func(*args,**kwargs):
    print('The python is perfect!')
    @warpper
    def func1(*args,**kwargs):
    print('The js is good!')

    func()
    func1()
    #输出:

      nice
      The python is perfect!
      bad
      nice
      The js is good!
      bad

     假如很多函数使用了一个装饰器,想要取消部分装饰器怎么办呢?

    def outer(flag):
        def timer(func):
            def inner(*args,**kwargs):
                ret = func(*args, **kwargs)
                if flag:
                    print(time.time())
                return ret
            return inner
        return timer
    @outer(True)
    def func():
        print('linux')
    func()
    
    #给装饰器再添加异常flag判断,当装饰器为False快速取消装饰器
    取消装饰器效果

    多个装饰器装饰一个函数的效果

    def warpper1(func):
        def inner(*args,**kwargs):
            print('w1情不知所起')
            ret = func(*args,**kwargs)
            print('w1一往而情深')
            return ret
        return inner
    def warpper2(func):
        def inner(*args,**kwargs):
            print('w2情不知所起')
            ret = func(*args,**kwargs)
            print('w2一往而情深')
            return ret
        return inner
    
    @warpper1   #  func = warpper1(warpper2.inner) 此时的func是被warpper1.inner
    @warpper2   #  func = warpper2(func) 此时的func是warpper2.inner
    def func():
        print('You can you up!')
    func()
    #输出结果
        w1情不知所起
        w2情不知所起
        You can you up!
        w2一往而情深
        w1一往而情深
    
    #执行步骤: 1.首先走wapper1.inner  因此首先打印'w1情不知所起',
             2.往下执行,遇到ret = func()执行调用,此时调用的其实是warpper2.inner,因此跳转到warpper2的inner,打印出'w2情不知所起',
             3.继续往下执行,再次遇到 ret = func().执行调用,此时调用的是原先的func函数,因此打印'You can you up!',
             4.往下执行,打印'w2一往而情深',
             5.由于warpper1函数并没有走完,因此回去再次往下执行,打印'w1一往而情深'.
    多个装饰器装饰一个函数

    装饰器的修复技术

    示例1
    from functools import wraps
    
    def ww(func):
        #@wraps(func)
        def inner(*args,**kwargs):
            ret = func(*args,**kwargs)
            return ret
        return inner
    
    @ww
    def func():
        '''
        你好
        :return:
        '''
        pass
    func()
    print(func.__name__)
    print(func.__doc__)
    
    #输出结果
        inner
        None   
    对比示例2 来看更加清晰
    示例2
    from functools import wraps
    
    def ww(func):
        @wraps(func)
        def inner(*args,**kwargs):
            ret = func(*args,**kwargs)
            return ret
        return inner
    
    @ww
    def func():
        '''
        你好
        :return:
        '''
        pass
    func()
    print(func.__name__)
    print(func.__doc__)
    #输出
    func
    
        你好
        :return:
    #由此看到添加@warps(func)后 被装饰过的func函数名称再调用的时候就是func了,也可以看到 func函数的注释等
    装饰器的修复技术

     总结:巧妙的运用装饰器函数是非常重要的

    ...

    CrazyShenldon
  • 相关阅读:
    pyhton 163 email ssl attach file
    Database creation error: relation "ir_model" does not exist LINE 1: SELECT * FROM ir_model WHERE state='manual' ^
    爬虫心得
    WSL windows子系统ubuntu18.04建设自己的乌云
    WSL windwos 子系统 ubuntu18.04安装mysql
    python 163 email 554
    自定义的应用层协议(转)
    嵌入式杂谈之文件系统(转)
    linux VFS
    C++之保护和私有构造函数与析构函数
  • 原文地址:https://www.cnblogs.com/CrazySheldon1/p/10306314.html
Copyright © 2011-2022 走看看