Loading

Python 装饰器

首先

3c200f789a7f429b98afcf664f349545 (236×127)

4f1e63d80fbe4f9c834614fec5b3d685 (419×180)

需求来了

有如下几个封装好的函数供调用:

eaca74bdfc4b4623bd89783d2ad1594a (191×196)

现在需要在每个函数执行前进行日志记录:

第一个方案

44ac4baefba44b6e8925e55df2d09a6f (233×278)

修改每个函数,添加日志记录的代码

但这样显然不太好,存在大量的重复代码,可以将重复代码封装为一个方法

第二个方案

810fd336834c41abbe6f5813928968ed (234×317)

这样的确是比第一个方案好多了,但是不符合开闭原则,即现有的代码不要去修改,而在基础的功能上进行二次开发

第三个方案

c1e38aa654b24413994e69514f5f7e52 (252×355)

这样的确很好,但是在调用的时候太麻烦了,而且函数名字也变了,以前写好的代码全部都要修改,想办法让函数名不变就好了

第四个方案

71ddf9645f4d4eddaeb6125e57a61078 (281×403)

这样就又好点了,在增加功能而不修改代码的前提下,也保证了函数名不变

这就是装饰器的功能了,装饰器和上边的代码实现的功能相同,只不过用了语法糖

使用装饰器的方案

7fd6644fc2d843f69a3a808bd354e99d (246×447)

装饰器原理

上述代码在执行@verify时,进行了如下操作:

执行verify函数 ,并将 @verify 下面的函数作为verify函数的参数

即@verify 等价于 verify(f1) , 其内部执行代码如下:

f1 = verify(f1)

如此便为装饰器

小小装饰器

146c5f8d58ce4524a3cde597ee5ff925 (381×538)

输出结果:

eb674482b1d04e95907b561e55915d66 (360×95)

装饰器的常用功能

  1. 引入日志
  2. 函数执行时间统计
  3. 执行函数前预备处理
  4. 执行函数后清理功能
  5. 权限校验等场景
  6. 缓存

装饰器实例

1.无参数的函数

ee1c370f3de5432e83aaa7bfbfcc51ab (596×320)

2.被装饰的函数有参数

842268583a2b40e68c711d105797fac5 (609×365)

3.被装饰的函数有不定长参数

1edae981654041d28d9f9eb4193cc93e (599×396)

4.装饰器中的return

057a5b6057a949c4879574a1b5b0cbd3 (593×387)

执行结果

aeca4ec70ad84a0db57c8615c6b0a864 (469×143)

如果修改装饰器为 return func(),则运行结果:

4c167fbea2a84d57b50053a42a999388 (470×150)

所以,一般情况下为了让装饰器更通用,可以有return

5.装饰器带参数,在原有装饰器的基础上,设置外部变量

65c5dba4044b4a2d93007bcfe2b221b5 (640×454)

运行结果为:

229fdd74d2eb49b4a1eb9edd3acfad80 (503×277)

可以理解为:

foo()==timefun_arg("itcast")(foo)()

posted @ 2019-01-02 20:50  烟草的香味  阅读(228)  评论(0编辑  收藏  举报