您的位置:聚讯网络 > 新闻动态 > 行业新闻 >

【更新带动器】「python3入门视频教程」6.4 python装饰器详解

日期:2018/06/12     阅读:     来源:网络整理
更新带动器】「python3入门视频教程」6.4 python装饰器详解 >>>点击查看 6.3 返回函数与闭包


【更新带动器】「python3入门视频教程」6.4 python装饰器详解


装饰器(Decorator)是python中最吸引人的特性,装饰器本质上还是一个函数,它可以让已有的函数不做任何改动的情况下增加功能。非常适合有切面需求的场景,比如权限校验,日志记录和性能测试等等。比如你想要执行某个函数前记录日志或者记录时间来统计性能,又不想改动这个函数,就可以通过装饰器来实现。

以日志为例

定义一个计算平方的函数,然后调用:


【更新带动器】「python3入门视频教程」6.4 python装饰器详解


现在想在计算平方开始 和 结束打上标示,正常情况会去修改原函数,像这样


【更新带动器】「python3入门视频教程」6.4 python装饰器详解


从功能实现来看,这样是ok的。唯一的问题就是它需要侵入到原来的代码里面,把日志逻辑加上去,那么有没有可能在不修改业务代码的提前下,实现日志功能呢?用装饰器就能实现这一功能。因为函数可以作为另外一个函数的传参或者返回。也可以把函数赋值给一个变量。这里定义一个 squareLog 函数。传入一个函数参数,并且返回一个函数。


【更新带动器】「python3入门视频教程」6.4 python装饰器详解


这里并没有修改原函数。只是把square指向了经过 squareLog 处理过后的函数。这里的 squareLog 其实就相当于一个装饰器。本质上是一个闭包。在python中因为对装饰器提供了语法糖(@)的支持。所以使用装饰器会显得更加强大。上面的写法在python中可以修改如下:


【更新带动器】「python3入门视频教程」6.4 python装饰器详解


这样既可以在不用修改原函数 ,也可以不用修改调用方法。就可以实现需要的日志功能

装饰器函数也可以传入参数。写法跟之前稍微有点不一样。


【更新带动器】「python3入门视频教程」6.4 python装饰器详解


不用语法糖 相当于下面这样


【更新带动器】「python3入门视频教程」6.4 python装饰器详解


使用 print(square.__name__) 打印函数名称,,会发现函数名已经改变。如何保持函数名不变呢

使用 wraps


【更新带动器】「python3入门视频教程」6.4 python装饰器详解


下面是输出结果:

square log

func name square

start

x*x= 25

end

这里可能有些人看到有点诡异。为什么 func name square 的输出 是在 square log 下面。而不是上面。

我们看看没有用语法糖时候的写法。

wrap = log('square')

square = wrap(square)

square(5)

这里可以看出在我们使用 square.__name__ 的时候,要先执行 wrap = log('square')。所以输出就想上面这样

一个函数可以使用多个装饰器函数,执行顺序为从下到上。但又不是单纯的从下到上

不用语法糖的情况


【更新带动器】「python3入门视频教程」6.4 python装饰器详解


【更新带动器】「python3入门视频教程」6.4 python装饰器详解


解析:

执行完 square = log(square) 后

#这时候square相当于 这个函数


【更新带动器】「python3入门视频教程」6.4 python装饰器详解


执行完 square = sleep(square)。相当于把wrap函数传入 sleep 中。主意这个时候的sleep中的func是log中的square。于是输出就是下面这样了

输出:

log

sleep

start sleep

start

x*x= 25

end

end sleep

相当于


更多>>相关文章