本篇文章小编给大家详细介绍一下Python装饰器详细介绍,如果有兴趣的小伙伴一定要耐心阅读完这篇文章,小编希望这篇文章能够给大家的学习带来一定的帮助 。
文章插图
什么是python装饰器?其实装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.
经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景 。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用 。
先来看一个简单例子:
def now(): print('2017_7_29')现在有一个新的需求,希望可以记录下函数的执行日志,于是在代码中添加日志代码:
def now(): print('2017_7_29') logging.warn("running")假设有类似的多个需求,怎么做?再写一个logging在now函数里?这样就造成大量雷同的代码,为了减少重复写代码,我们可以这样做,重新定义一个函数:专门处理日志,日志处理完之后再执行真正的业务代码.
def use_logging(func): logging.warn("%s is running" % func.__name__) func() def now(): print('2017_7_29') use_logging(now)在实现,逻辑上不难,但是这样的话,我们每次都要将一个函数作为参数传递给日志函数 。而且这种方式已经破坏了原有的代码逻辑结构,之前执行业务逻辑时,执行运行now(),但是现在不得不改成use_logging(now) 。
那么有没有更好的方式的呢?当然有,答案就是装饰器 。
首先要明白函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数 。例如:
(=简单装饰器
本质上,decorator就是一个返回函数的高阶函数 。所以,我们要定义一个能打印日志的decorator,可以定义如下:
def log(func): def wrapper(*args,**kw): print('call %s():'%func.__name__) return func(*args,**kw) return wrapper# 由于log()是一个decorator,返回一个函数,所以,原来的now()函数仍然存在,# 只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在log()函数中返回的wrapper()函数 。# wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用 。# 在wrapper()函数内,首先打印日志,再紧接着调用原始函数 。上面的log,因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数.现在执行:
now = log(now)now()#输出结果:call now():2017_7_28函数log就是装饰器,它把执行真正业务方法的func包裹在函数里面,看起来像now被log装饰了 。在这个例子中,函数进入时,被称为一个横切面(Aspect),这种编程方式被称为面向切面的编程(Aspect-Oriented Programming) 。
使用语法糖:
@logdef now(): print('2017_7_28')@符号是装饰器的语法糖,在定义函数的时候使用,避免再一次赋值操作
这样我们就可以省去now = log(now)这一句了,直接调用now()即可得到想要的结果 。如果我们有其他的类似函数,我们可以继续调用装饰器来修饰函数,而不用重复修改函数或者增加新的封装 。这样,我们就提高了程序的可重复利用性,并增加了程序的可读性 。
推荐阅读
- JSON在Python中的使用介绍!干货!值得大家的收藏
- python序列列表怎么排序?这几种方法一定有你不知道的
- python字符串前面加r是为什么?具体原因来了
- python中如何将键值对添加到字典中?必须要会的方法来了
- python3中怎么清屏?超详细的教程来了
- Python要怎么去编写一个可交互文本菜单?详细代码示例和教程在这里
- python系统命令乱码如何解决?这篇文章你一定要看
- python长字符如何换行?这三个方法你不一定都知道
- Python要怎么去对字符串验证正则表达式?Python正则的使用方法
- 如何使用Python 操作PDF?总结用Python操作PDF的几种方法