Python3装饰器

装饰器:本质是函数(装饰其他函数-->为其他函数添加功能)
原则:1.不能被修改装饰的源代码
2、不能修改被装饰的函数的调用方式
知识储备:
1、函数即“变量”
2、高阶函数
3、嵌套函数
高阶函数+嵌套函数 = 装饰器

高阶函数:
a.把一个函数名当做实参传给另一个函数

b.返回值中包含函数名
嵌套函数:

仅用高阶函数实现的装饰器

高阶函数+嵌套函数:实现装饰器。

装饰器函数定义时,通过将需要装饰的函数(装饰器的形参)放在嵌套函数里面,嵌套在内层的函数只进行函数定义,不进行函数的调用(内含的被装饰的函数就不会运行)。然后将装饰后的的嵌套函数地址返回。


装饰器用法:想装饰什么函数,就在哪个函数上一行头部 @装饰器名称

@装饰器名称

函数名

即:如下写法的简化写法

foo = deco(foo)
foo()
DeBug过程详解:
  1、定义装饰器deco
  2、调用deco
  2.1、调用deco过程中:定义替换test1的函数timmer(foo函数)
  2.2、调用deco过程中:返回定义的函数timmer(装饰后的foo函数),但是不做任何调用
  3、调用装饰后的foo函数timmer
  3.1、调用timmer过程中,先运行装饰的代码
  3.2、调用timmer过程中,运行原始foo的调用。
  3.3、调用timmer过程中,再运行装饰代码。
  GAME OVER 完美完成!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
通用性装饰器,被装饰的函数输入参数不固定

 高级多功能装饰器(装饰器带参数)

wraps函数

使用装饰器时,有一些细节需要被注意。例如,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变)。

添加后由于函数名和函数的doc发生了改变,对测试结果有一些影响,例如:

def note(func):
    "note function"
    def wrapper():
        "wrapper function"
        print('note something')
        return func()
    return wrapper

@note
def test():
    "test function"
    print('I am test')

test()
print(test.__doc__)

运行结果

note something
I am test
wrapper function

所以,Python的functools包中提供了一个叫wraps的装饰器来消除这样的副作用。例如:

import functools
def note(func):
    "note function"
    @functools.wraps(func)
    def wrapper():
        "wrapper function"
        print('note something')
        return func()
    return wrapper

@note
def test():
    "test function"
    print('I am test')

test()
print(test.__doc__)
#运行结果

note something
I am test
test function
原文地址:https://www.cnblogs.com/zhangmingda/p/9053948.html