Python的装饰器能够实如今代码运行期间修改函数的上下文, 便可以定义函数在执行以前进行何种操做和函数执行后进行何种操做, 而函数自己并无任何的改变。segmentfault
这个看起来很复杂, 实际上应用到了我以前说过的闭包的概念, 仔细看一看, 其实并不复杂。闭包
首先, 咱们先定义一个函数, 这个函数能够输出个人我的昵称:app
def my_name(): print "Yi_Zhi_Yu" my_name() # Yi_Zhi_Yu
那假如我须要在我的昵称输出前, 在输出个人我的uid呢, 固然, 要求是不改动现有的my_name函数, 这个时候就可使用装饰器了函数
首先, 装饰器也是个函数, 其次, 他须要接受一个参数,该参数表示了要被装饰的函数(即my_name):oop
def my_info(func): def wrapper(*args, **params): print 218 return func(*args, **params) return wrapper
而后与相应的被装饰函数关联起来的方法就是使用@my_info
写在被装饰函数的前面学习
@my_info def my_name(): print "Yi_Zhi_Yu"
最后, 在执行my_name的时候, 就能既输出个人uid, 又能输出个人昵称了ui
my_name() #218 #Yi_Zhi_Yu
在上面, 最让咱们疑惑的是装饰器函数定义里面的wrapper函数, 装饰器自己返回的是wrapper函数的定义, 而wrapper中则定义了对被装饰函数(my_name)的调用, func表示的就是被装饰函数, 说白了, 装饰器只是把某个不得改动的函数(a)放到另外一个函数(b)中, 在b里面调用a, 在调用先后就能够作所谓的看起来像装饰的工做了。
my_info的最终返回的wrapper函数的定义, 并非执行结果,只有当wrapper真正执行的时候, 才会真正的执行my_name方法, 这就是闭包时所说的内容。
wrapper中的参数, 实际上则是传递给func(其实是my_name)的参数code
由于装饰器也是个函数, 那么装饰器本身的能不能有参数传递呢。能够, 不过须要定义一个更高阶的函数, 也就是外面还要套一层函数, 好比, 我还要输出个人自定义的一个信息,须要传递参数get
def c_info(text): def my_info(func): def wrapper(*args, **params): print text print 218 return func(*args, **params) return wrapper return my_info #使用装饰器 @c_info("Tony") def my_name(): print "Yi_Zhi_Yu" my_name() #Tony #218 #Yi_Zhi_Yu
与前面的那个装饰器相比, 仅仅是多了个外层, 内层也仅仅是增长了对外层传入参数(text)的调用学习笔记
总而言之, Python在函数定义中支持了对oop思想中的装饰器的实现, 其本质也只是使用了闭包的思路, 延迟调用, 并在调用先后增长本身的其余实现内容
Ps: 以上皆为学习笔记, 附带本身的理解, 不免有误差, 若有发现纰漏, 还望指正