洗礼灵魂,修炼python(30)--装饰器(2)—>装饰器总结+进阶使用
2018-03-07 21:10
936 查看
在上一篇博文的经典案例中,我想你应该对装饰器有很好的了解了,不过光有那些还不够真的,还需要总结和进阶一下,所以本篇博文解析装饰器进阶。
装饰器
1.什么是装饰器?个人理解:装饰器又叫语法糖,指的是对原程序内部整个代码不作任何更改,在外部写好一个带某种功能的程序来作用于原程序,对其进行修饰或者叫装饰,这就是装饰器。还有两种理解是:1).在代码运行期间动态增加功能的方式,称之为“装饰器”2).装饰器,允许向一个现有的对象添加新的功能,同时又不改变其结构。作为现有对象的一个包装2.格式:def func(): suite @func def func1(): suite@func即表示装饰器,这个写法等价于func=func(func1)例子:一般用法:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/8fc0642f24d471a1444a0d33e3ce0aae.png)
使用装饰器:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/6c34d68fec6d8446a56646a6499c36cb.png)
是的,你发现了,其实两个写法得到的结果是一样的。所以印证前面那句话,是等价的即:
![](http://blog.csdn.net/y_morph/article/details/ht<br/>d3a1<br/>tp:/images2017.cnblogs.com/blog/1249183/201710/1249183-20171013171059980-1753831891.png)
等价于:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/b699d530ecaa2fc9bb317782b52b34fa.png)
4.装饰器的作用:1).装饰器可以极大的简化代码,避免每个函数编写重复性代码2).装饰器在实际的开发中很实用,不需要修改原代码,直接对其进行重新扩展功能即可3).装饰器遵循封闭开放原则。封闭:已实现的功能代码块
开放:对扩展开发
5.装饰器内装饰的函数一样可以传入参数:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/b5a8df0658281145698b311c429d9d40.png)
外层函数传入的是函数对象作为参数,内层函数传入的是外层函数的传入的函数的参数作为参数,听起来有点拗口,集合看上面的例子看你就懂了6.一个函数可以被多个装饰器装饰
def outer1(func): def inner(*args,**kwargs): print("认证成功!") return func(*args,**kwargs) return inner def outer2(func): def inner(*args,**kwargs): print("开始解决第一个项目问题") return func(*args,**kwargs) return inner def outer3(func): def inner(*args,**kwargs): print('开始解决第二个项目问题') return func(*args,**kwargs) return inner @outer1 @outer2 @outer3 def bumen1(name,age): print("%s 正在连接部门1数据接口......"%name) bumen1("yang",21)结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/bae971e12b3b70c9e83b3884dd48bb59.png)
7.装饰器自身也可以带参数1).装饰器带参数,函数不带:
def out(arg): def inner1(func): def inner2(): print("before %s called [%s]." % (func.__name__, arg)) func() print("after %s called [%s]." % (func.__name__, arg)) return inner2 return inner1 @out("module2") def myfunc(): print("myfunc() called.") myfunc()结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/e914a7f9b373ea2c56f78b88cfa14c50.png)
2).装饰器和函数都带参数:
def out(arg): def inner1(func): def inner2(num): print("before %s called [%s]." % (func.__name__, arg)) print(func(num)) print("after %s called [%s]." % (func.__name__, arg)) return inner2 return inner1 @out("mymodule") def myfunc1(num): print("myfunc1(%d) called."%num) return 'the args is :%d'%num myfunc1(2)结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/6ff0eb63642528d1c5136a547b6b4951.png)
绕晕了?没看明白吧?来个简单点的:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/f78baaeac374b7fbdfed5a9c9a6ea374.png)
3).装饰器还可以带多个参数或者默认参数,用*args,**kwargs表示即可,这个什么类型的参数在前面讲过的,这里直接略过。传入多个参数方法和传入一个参数是一样的,不再解析 其实你应该发现了,装饰器带参数其实就是在两层的基础上又加了一层来为装饰器传参的。
8.装饰器传入函数作为参数
这个想想就觉得厉害了对不?def auth(request,*kargs): print('认证成功') def error_debug(request,*kargs): print('日志记录成功') def out(auth_func,debug_func): def inner1(func): def inner2(request,*kargs): auth_func=auth(request,*kargs) #主体只是print的函数没有返回值,为空。不信的话你可以定义一个并打印看看就明白 #当有异常抛出时不为空,所以这里设置不为空提前结束程序并返回异常 if auth_func!=None: return auth_func main_func=func(request,*kargs) if main_func!=None: return main_func error_func=error_debug(request,*kargs) if error_func!=None: return error_func return inner2 return inner1 @out(auth,error_debug) def func(name,*age): print('%s正在开发项目'%name) func('yang')结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201803/99f6b66fdb3c749487cb310dd271cb98.png)
好的装饰器就到这,具体的开发运用的话,装饰器可以用到很多,比如可以传入一个类对象,传入另一个装饰器,还有在做项目时,写好一个框架,把框架作为装饰器等等的。具体的自己研究吧,反正装饰器挺强大的。 简单练习:(据说这是一道面试题)请利用装饰器的方法将下面函数返回的结果小写:def upper_func(string): return string.uppper()upper_func(I Play Basketball')
相关文章推荐
- 洗礼灵魂,修炼python(29)--装饰器(1)—>利用经典案例解析装饰器概念
- 洗礼灵魂,修炼python(15)--列表进阶话题—>列表解析/列表生成器
- 洗礼灵魂,修炼python(23)--自定义函数(4)—闭包进阶问题—>报错UnboundLocalError: local variable 'x' referenced before assign
- 洗礼灵魂,修炼python(25)--自定义函数(6)—从匿名函数进阶话题讲解中解析“函数式编程”
- 洗礼灵魂,修炼python(27)--异常处理(1)—>了解异常
- 洗礼灵魂,修炼python(18)--温故加知新
- 洗礼灵魂,修炼python(5)--python操作符,内置函数
- 洗礼灵魂,修炼python(11)--python函数,模块
- 洗礼灵魂,修炼python(13)--模块random,math,pickle
- 洗礼灵魂,修炼python(6)--活起来的代码+列表
- 洗礼灵魂,修炼python(34)--面向对象编程(4)—继承
- 【转帖】使用python爬虫抓站的一些技巧总结:进阶篇
- 洗礼灵魂,修炼python(26)--编程核心之“递归”
- python-->django使用过程中碰到的异常总结
- 洗礼灵魂,修炼python(19)--文件I/O操作,linecache,fileinput模块
- Python进阶强化训练之装饰器使用技巧进阶
- 洗礼灵魂,修炼python(10)--有趣的判断分支+从实例中掌握循环语句
- 洗礼灵魂,修炼python(1)--python简介
- 洗礼灵魂,修炼python(20)--自定义函数(1)—基础概念
- Python装饰器-专题笔记-学会装饰器,Python更进阶