一、

装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

二、装饰器工作原理。

遵循编程的闭合原则,在不修改原函数代码的基础上增加功能,使用装饰器是一种很好的选择。

装饰器工作基于以下两步完成:

第一步:被装饰的函数作为参数传给装饰器函数,并执行装饰器函数,返回值记作newFunction;

第二步:原函数名重新被赋值为newFunction。

def auth(fun):   #定义装饰器
def inner():
print("The test code")
fun()
print("after")
return inner @auth #相当于 f1 = auth(f1) 也叫加载装饰器
def f1(): #被装饰的函数
print("----f1执行过程----") f1() #调用函数 #执行结果为 The test code
# ----f1执行过程----
# after

当执行f1函数时,首先执行装饰器auth,并将原f1函数作为参数传递给装饰器函数,装饰器返回一个inner函数并将该函数赋值给f1,即f1() = inner()

auth 这个函数实现的功能是,接收一个函数作为参数然后返回创建的另一个函数f1()=inner(),在这个创建的函数里调用接收的函数(文字比代码绕人)

三、动态参数,装饰含有N个参数的函数。

def auth(fun):   #定义装饰器
def inner(*args,**kwargs): #定义动态参数
print("The test code")
fun(*args,**kwargs) #将动态参数传给原函数
print("after")
return inner @auth #相当于 f1 = auth(f1) 也叫加载装饰器
def f1(): #被装饰的函数
print("----f1执行过程----\n===========")
@auth
def f2(name,age):
print("f2执行过程:name is + %s; age is + %s" %(name,age))
f2("gyc",33) #执行结果为

#The test code
#f2执行过程:name is + gyc; age is + 33
#after

装饰含有不同参数个数及格式的函数,可以给装饰器定义动态参数,由装饰器将动态参数传递给原函数

四、装饰有返回值的函数。

def outer(func):      #定义装饰器
def inner(*args,**kwargs): #为inner函数定义返回值
print("执行原函数之前")
r = func(*args,**kwargs) #接受原函数的返回值
print("执行原函数之后")
return r #返回原函数的返回值
return inner
@outer
def f1():
print("f1执行过程")
@outer
def f2(name,age):
print("f2执行过程")
rst = 'name is '+name+';age is'+age
return rst r1 = f1()
print("不接受参数,且无返回值:%s"%r1) r2 = f2('gyc','')
print("接受参数,且有返回值:%s"%r2)

执行结果

五、多层装饰器(同时加载多个装饰器)

六、带参数的装饰器

带参数的装饰器更为灵活,可以接收任意函数作为参数,然后动态生成新的基础装饰器,然后用新装饰器去装饰原函数。

这样,可以指定在原函数执行前运行某一个程序,在原函数执行之后运行另一个程序。

最新文章

  1. 01.SQLServer性能优化之---水平分库扩展
  2. Tomcat内存溢出的三种情况及解决办法分析
  3. Leetcode 1 two sum 难度:0
  4. POJ 1703 Find them, Catch them(种类并查集)
  5. 修改webapp底图
  6. log4j记录运行日志
  7. Verilog-1995 VS Verilog-2001
  8. sea.js,spm学习
  9. 【转】Xcode7真机调试iOS应用程序
  10. 实现多文件上传在iOS开发中
  11. 二、spring Boot构建的Web应用中,基于MySQL数据库的几种数据库连接方式进行介绍
  12. DeepLearning.ai学习笔记(四)卷积神经网络 -- week1 卷积神经网络基础知识介绍
  13. Collections与Collection
  14. Unity 如何检测鼠标双击事件
  15. ubuntu 精简配置
  16. VUE2.0 饿了吗视频学习笔记(二):新版本添加路由和显示Header
  17. luogu P2508 [HAOI2008]圆上的整点
  18. Spring实现Ioc的多种方式--控制反转、依赖注入、xml配置的方式实现IoC、对象作用域
  19. c#内存中创建反射
  20. mysql中的delete , drop 和truncate 区别

热门文章

  1. js 页面刷新location.reload和location.replace的区别小结
  2. [LeetCode] Course Schedule 课程清单
  3. FineUI(开源版)v6.0中FState服务器端验证的实现原理
  4. Android系统中应用的安装和卸载的监听
  5. 给织梦添加英文栏目标题在chanel标签中调用
  6. XMind共享未保存的思维导图的教程
  7. JsonResult类设置返回json的长度(工作笔记 json转化出错)
  8. BZOJ 4742: [Usaco2016 Dec]Team Building
  9. C#工具代码
  10. QEMU/KVM虚拟机安装配置