定义了一些函数,这些函数都要被外部所调用,但是这些函数在被调用之前,都有些相同的功能需要被实现,在这种情况下,装饰器是最好的解决方案:
def f1(): print ("F1") def f2(): print ("F2")
在另一个模块中调用的时候
import s1 s1.f1() s1.f2()
执行结果:
F1
F2
这个时候,我们需要在f1,f2中分别添加打印日志的功能,于是,函数的定义变成了
def f1(): print ("log") print ("F1") def f2(): print ("log") print ("F2")
在模块中调用执行的结果是:
log
F1
log
F2
这个时候整个函数都要修改,工作量非常之大,于是想到了用一个函数来定义日志的打印功能
def log(): print ("log")
def f1(): log() print ("F1") def f2(): log() print ("F2")
通过这样改变代码,我们也可以实现功能,而且每次都只需要修改函数的内容即可。但是这样还是改变了f1,f2函数体的内容,违反了开放封闭原则(函数内的不要修改,函数外的可以修改)
def outer(func): def inner(): print ("log") func() return inner @outer #f1 = outer(f1) def f1(): print ("F1") @outer def f2(): print ("F2")
装饰器的内层原理:@outer有两个功能:1,自动执行outer函数,并且将其紧挨的下面的函数名f1传递给outer函数;2,将outer函数的返回值重新赋值给了f1函数
带返回值的装饰器
def outer(func): def inner(): print ("before") func() print ("after") return inner # @outer def f2(): print ("F2") return "SB"
在另一个模块调用,没有使用装饰器的前提下(有返回值):
r = s1.f2() print (r) 结果: F2 SB
添加了装饰器之后,代码改为下面的格式(没有记录返回值):
def outer(func): def inner(): print ("before") func() print ("after") return inner @outer def f2(): print ("F2") return "SB" 执行结果: before F2 after None
打印的结果跟我们需要的不一致(我们需要记录到返回值),于是重新修改了装饰器代码:
def outer(func): def inner(): print ("before") r = func() print ("after") return r return inner @outer def f2(): print ("F2") return "SB" 执行结果: before F2 after SB
定义带参数的装饰器
def outer(func): def inner(a): print ("before") r = func(a) print ("after") return r return inner @outer def f2(a): print (a) return "SB" 在模块中调用 r = s1.f2("ffffff") print (r) 执行结果: before ffffff after SB
原文:http://www.cnblogs.com/python-study/p/5652072.html