Python装饰器
来源:互联网 发布:python 数据清洗 框架 编辑:程序博客网 时间:2024/06/01 07:45
装饰器背后的主要动机源自Python面向对象编程。
装饰器是在函数调用之上的修饰。这些修饰仅是当声明一个函数或者方法的时候,才会应用的额外调用。
装饰器的语法是以@开头,接着是装饰器函数的名字和可选参数。紧跟着装饰器声明的是被修饰的函数和装饰函数的可选参数。如:
@decorator(dec_opt_args)
def func2Bdecorator(func_opt_args):
...
...
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
1、装饰器可以如函数调用一样“叠加”,如:
@deco2
@deco1
def func(arg1, arg2, ...): pass
这和创建一个组合函数是等价的。
def func (arg1, arg2, ...): pass
func = deco2(deco1(func))
2、手动装饰
# 装饰器是一个函数,而其参数为另外一个函数
def my_shiny_new_decorator(a_function_to_decorate) :
# 在内部定义了另外一个函数:一个封装器。
# 这个函数将原始函数进行封装,所以你可以在它之前或者之后执行一些代码
def the_wrapper_around_the_original_function() :
# 放一些你希望在真正函数执行前的一些代码
print "Before the function runs"
# 执行原始函数
a_function_to_decorate()
# 放一些你希望在原始函数执行后的一些代码
print "After the function runs"
#在此刻,"a_function_to_decrorate"还没有被执行,我们返回了创建的封装函数
#封装器包含了函数以及其前后执行的代码,其已经准备完毕
return the_wrapper_around_the_original_function
# 现在想象下,你创建了一个你永远也不远再次接触的函数
def a_stand_alone_function() :
print "I am a stand alone function, don't you dare modify me"
a_stand_alone_function()
#输出: I am a stand alone function, don't you dare modify me
# 好了,你可以封装它实现行为的扩展。可以简单的把它丢给装饰器
# 装饰器将动态地把它和你要的代码封装起来,并且返回一个新的可用的函数。
a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function_decorated()
#输出 :
#Before the function runs
#I am a stand alone function, don't you dare modify me
#After the function runs
现在你也许要求当每次调用a_stand_alone_function时,实际调用却是a_stand_alone_function_decorated。实现也很简单,可以用my_shiny_new_decorator来给a_stand_alone_function重新赋值。
a_stand_alone_function = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function()
#输出 :
#Before the function runs
#I am a stand alone function, don't you dare modify me
#After the function runs
# And guess what, that's EXACTLY what decorators do !
3、装饰器揭秘
前面的例子,我们可以使用装饰器的语法:
@my_shiny_new_decorator
def another_stand_alone_function() :
print "Leave me alone"
another_stand_alone_function()
#输出 :
#Before the function runs
#Leave me alone
#After the function runs
当然你也可以累积装饰:
def bread(func) :
def wrapper() :
print "</''''''\>"
func()
print "<\______/>"
return wrapper
def ingredients(func) :
def wrapper() :
print "#tomatoes#"
func()
print "~salad~"
return wrapper
def sandwich(food="--ham--") :
print food
sandwich()
#输出 : --ham--
sandwich = bread(ingredients(sandwich))
sandwich()
#outputs :
#</''''''\>
# #tomatoes#
# --ham--
# ~salad~
#<\______/>
使用python装饰器语法:
@bread
@ingredients
def sandwich(food="--ham--") :
print food
sandwich()
#输出 :
#</''''''\>
# #tomatoes#
# --ham--
# ~salad~
#<\______/>
装饰器的顺序很重要,需要注意:
@ingredients
@bread
def strange_sandwich(food="--ham--") :
print food
strange_sandwich()
#输出 :
##tomatoes#
#</''''''\>
# --ham--
#<\______/>
# ~salad~
最后回答前面提到的问题:
# 装饰器makebold用于转换为粗体
def makebold(fn):
# 结果返回该函数
def wrapper():
# 插入一些执行前后的代码
return "<b>" + fn() + "</b>"
return wrapper
# 装饰器makeitalic用于转换为斜体
def makeitalic(fn):
# 结果返回该函数
def wrapper():
# 插入一些执行前后的代码
return "<i>" + fn() + "</i>"
return wrapper
@makebold
@makeitalic
def say():
return "hello"
print say()
#输出: <b><i>hello</i></b>
参考
理解Python装饰器
http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html
Python核心编程(第二版)
- python装饰器装饰类
- [python]python装饰器
- Python装饰器学习
- Python装饰器
- python 装饰器
- Python装饰器
- python 装饰器 应用
- python 装饰器2
- Python装饰器学习
- python装饰器
- python装饰器
- python 装饰器入门
- python装饰器
- python装饰器
- python 装饰器'@'
- python装饰器
- Python装饰器详解
- python 装饰器
- Spring destroy-method="close"的作用
- GCC主要数据结构之c_typespec_keyword
- xgboost ppt(3)——GB
- Android应用程序组件间通信(二)——IntentFilter类简介
- 美团点评前端无痕埋点实践
- Python装饰器
- solr入门基础(windows jettry)
- GCC主要数据结构之c_declspec_word
- [字符识别系列][一] 字符识别中的图像归一化算法简介
- 什么是正向代理与反向代理
- linux下如何修改iptables开启80端口
- 深入浅出ES6(二):迭代器和for-of循环
- Merge Intervals:动态规划,这题不能用a[i]和a[i-1]。
- 数据库查询含有字段的表