python 装饰器模式 我的理解
2016-01-12 17:20
447 查看
python和javascript类似, 可以把函数当作函数的返回值, 比如
在python中还有一个语法糖的概念, 有了它装饰器模式的实现代码可以更加简洁.示意如下:
把装饰函数的名字和@符号,放到被装饰函数的上一行,python就会自动开启装饰器模式.
但是语法糖有一个问题要注意.语法糖对函数的包装只会在编译代码时进行一次.也就是说在编译的时候,python会自动执行:
所以如果你运行上面这段代码, 编译时会输出:
运行最后两个myfunc()时,又会输出:
也就是这篇文章第三步中提到的运行结果.正确的方法是定义一个函数,用这个函数作为返回值代替被装饰的函数.
一个函数可以被多个装饰函数包装, 比如语法糖的顺序是
此外装饰器还可以带参数, 在这种情况下装饰函数就会再多一层函数嵌套:
此外被装饰的函数也可以带参数, 装饰函数的参数还可以是一个类 等等, 我就不一一举例了,大家可以看看这几篇文章:
http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html http://www.cnblogs.com/wilber2013/p/4657155.html
def func(f): def subfunc(): print 'subfunc' return subfunc此外func的参数f也可以是一个函数,正是这样的结构让python可以实现装饰器模式
def deco(func): print("before myfunc() called.") func() print(" after myfunc() called.") return func def myfunc(): print(" myfunc() called.") myfunc = deco(myfunc) myfunc()可以看到myfunc被deco包装了一下,在执行前的切面和执行后的切面都增加了一段代码,这就是装饰器的作用.
在python中还有一个语法糖的概念, 有了它装饰器模式的实现代码可以更加简洁.示意如下:
def deco(func): print("before myfunc() called.") func() print("after myfunc() called.") return func @deco def myfunc(): print("myfunc() called.") myfunc() myfunc()
把装饰函数的名字和@符号,放到被装饰函数的上一行,python就会自动开启装饰器模式.
但是语法糖有一个问题要注意.语法糖对函数的包装只会在编译代码时进行一次.也就是说在编译的时候,python会自动执行:
myfunc = deco(myfunc)
所以如果你运行上面这段代码, 编译时会输出:
before myfunc() called. myfunc() called. after myfunc() called.
运行最后两个myfunc()时,又会输出:
myfunc() called. myfunc() called.
也就是这篇文章第三步中提到的运行结果.正确的方法是定义一个函数,用这个函数作为返回值代替被装饰的函数.
def deco(func): def _deco(): print("before myfunc() called.") func() print("after myfunc() called.") return _deco @deco def myfunc(): print(" myfunc() called.") return 0 myfunc() myfunc()
一个函数可以被多个装饰函数包装, 比如语法糖的顺序是
@deco_1 @deco_2 def func() pass那么装饰的顺序就是:
func =deco_1(deco_2(func))
此外装饰器还可以带参数, 在这种情况下装饰函数就会再多一层函数嵌套:
def deco(arg): def _deco(func): if arg: def wrapper(): print("True") rs = func() print("after myfunc() called.") return rs else: def wrapper(): print("False") rs = func() print("after myfunc() called.") return rs return wrapper return _deco @deco(True) def myfunc(): print(" myfunc() called.") return 1 aa = myfunc() print aa为什么呢? 因为包装过程是:
func = deco(1)(func)deco是一个带参数的函数, 而deco(arg)的返回值又是一个以函数为参数的"正常的"装饰函数. 而这个"正常的"装饰函数的返回值又是一个用来代替func()的已经包装好了的函数.
此外被装饰的函数也可以带参数, 装饰函数的参数还可以是一个类 等等, 我就不一一举例了,大家可以看看这几篇文章:
http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html http://www.cnblogs.com/wilber2013/p/4657155.html
相关文章推荐
- python 装饰器模式 我的理解
- 笨办法学Python学习笔记 练习17
- [Leetcode]@python 68. Text Justification
- python版hadoop和spark入门
- 有关在某个数组中查找一个值的算法(Python实现)
- python数字图像处理(9):直方图与均衡化
- 自学Python三 Python中的屠龙刀(续)
- 如何用Python脚本自动SVN Update
- python 工具pip的安装
- python练习-itertools模块
- python
- python笔记-print输出
- [Leetcode]@python 67. Add Binary
- Python简单读写Excel (xlwt, xlrd, xlutils)
- Python的更多内容
- python 查看插件命令 pip freeze 以及django3.4链接mysql
- python + opencv 中 kp(关键点) 的形式及提取坐标方法
- 【极客学院】-python学习笔记-4-单线程爬虫 (提交表单抓取信息,实战练习)
- [Leetcode]@python 66. Plus One
- 笨办法学Python学习笔记 练习16