经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Python » 查看文章
Python学习 :装饰器
来源:cnblogs  作者:初释衷年  时间:2018/10/17 9:06:15  对本文有异议

装饰器(函数)

装饰器作为一个函数,可以为其他函数在不修改原函数代码的前提下添加新的功能

装饰器的返回值是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等。

装饰器,可以让我们抽离出大量与函数功能本身无关的相同代码并在装饰器函数中使用

 

装饰器的三个重要要素:

一、作用域

二、高阶函数

三、闭包

一、作用域

在上一节的函数中,我们详细介绍了函数的4种作用域:

L.local,局部作用域;E.enclosing,嵌套作用域;G.global,全局作用域;B.built-in,内建作用域

作用域的优先搜索顺序:局部作用域>>外层嵌套作用域>>当前模块(嵌套函数中)的全局作用域>>python内置作用域;

二、高阶函数

把函数作为参数传入,即函数本身也可以作为一个变量,这样的函数称为高阶函数

高阶函数,就是为了让函数的参数能够接收到别的函数

三、闭包

闭包函数可以脱离函数,在函数的外部单独地进行调用

闭包 = 内部函数 + 定义函数时的环境

闭包的两个条件:1、拥有内部函数;2、对外部环境的一个变量进行引用

  1. def outer():
  2. x = 'Hello World!' #定义函数的变量(环境)
  3.  
  4. def inner(): #条件1,,inner是内部函数
  5. print(x) #条件2,对外部环境的一个变量进行引用
  6.  
  7. return inner #结论,内部函数inner就是一个闭包
  8.  
  9. f = outer()
  10. f()
  11. >>> Hello World!

 

装饰器

 Eg1.计算总用时的装饰器

  1. import time
  2.  
  3. def show_time(f):
  4. def inner():
  5. start = time.time()
  6. f()
  7. end = time.time()
  8. res = end - start
  9. print('总用时:',res)
  10. return inner
  11.  
  12. @show_time #效果相当于 func1=show_time(func1)
  13. def func1():
  14. print('-----------功能1-----------')
  15. time.sleep(2) # 延时2s
  16.  
  17. @show_time #效果相当于 func2=show_time(func2)
  18. def func2():
  19. print('-----------功能2-----------')
  20. time.sleep(3) # 延时3s
  21.  
  22. func1()
  23. func2()
  24. >>>-----------功能1-----------
  25. 总用时: 2.0070815086364746
  26. -----------功能2-----------
  27. 总用时: 3.0007598400115967

 Eg2.带参数的装饰器(如果被装饰的函数中有参数,则装饰器函数中也要带上参数

  1. import time
  2. def show_time(f):
  3. def inner(*args,**kwargs):
  4. start = time.time()
  5. f(*args,**kwargs)
  6. end = time.time()
  7. res = end - start
  8. print('总用时:',res)
  9. return inner
  10.  
  11. @show_time #效果相当于 func1=show_time(func1)
  12. def func3(*args,**kwargs):
  13. sums = 0
  14. for i in args:
  15. sums += i
  16. print('-----------加法器-----------')
  17. print('结果是:',sums)
  18.  
  19. func3(5,6,1,4)
  20. >>>-----------加法器-----------
  21. 结果是: 16
  22. 总用时: 0.0

 Eg3.带参数的装饰器(参数为设置的条件,判断是否需要执行修饰器)

  1. import time
  2. def flag(flag = 'False'):
  3. def show_time(f):
  4. def inner(*args,**kwargs):
  5. if flag == 'True':
  6. start = time.time()
  7. f(*args,**kwargs)
  8. end = time.time()
  9. print('time: %s'%(end-start))
  10. else:
  11. f(*args, **kwargs)
  12. return inner
  13. return show_time
  14.  
  15. @flag('True') # flag = 'True',运行总用时装饰器
  16. def add(*args,**kwargs):
  17. sum = 0
  18. for i in args:
  19. sum+=i
  20. print('-----add的运行结果-----')
  21. print(sum)
  22. time.sleep(1)
  23.  
  24. @flag('False') # flag = 'False',不运行总用时装饰器
  25. def add1(*args,**kwargs):
  26. sum = 0
  27. for i in args:
  28. sum+=i
  29. print('-----add1的运行结果-----')
  30. print(sum)
  31. time.sleep(1)
  32.  
  33. add(1,4)
  34. add1(1,4)
  35. >>> -----add的运行结果-----
  36. 5
  37. time: 1.0008649826049805
  38. -----add1的运行结果-----
  39. 5

 注意:

  • 我们在调用装饰器时,提供了其它参数,@flag()默认的参数为False,则不会输出总用时装饰器;
  • 当@flag()参数为True时,输出总用时。这样是在原有的装饰器上加了一层判断;
  • 当我们使用@flag(‘True’)调用的时候,Python能够发现这一层的封装,并把参数传递到装饰器的环境中;
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号