装饰器函数

Posted crazysheldon1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器函数相关的知识,希望对你有一定的参考价值。

装饰器函数

什么是装饰器函数?

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

装饰器函数的功能

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

技术分享图片
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函数的注释等
装饰器的修复技术

 

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

...

 

以上是关于装饰器函数的主要内容,如果未能解决你的问题,请参考以下文章

装饰器181029

python 装饰器

闭包函数,装饰器

[TimLinux] Python 装饰器

python装饰器

装饰器