要想了解裝飾器首先要了解閉包。
閉包:由外部函數(shù)與內(nèi)部函數(shù)組成,內(nèi)部函數(shù)通過調(diào)用外部函數(shù)的變量與返回內(nèi)部函數(shù)的引用形成閉包。如下代碼(因?yàn)楸救耸褂玫氖莗ython2.7的版本所以內(nèi)部函數(shù)使用外部函數(shù)的變量時(shí)使用的是mutable對(duì)象(可變對(duì)象,列表或者字典)對(duì)象。python3與python2的區(qū)別參見博客:http://www.jb51.net/article/78955.htm)
def outer():
count= [0]
def inner():
count[0] +=1
print(count[0])
return inner
上述例子中實(shí)現(xiàn)了一個(gè)函數(shù)調(diào)用功能自動(dòng)加1的功能。結(jié)果如下:
if __name__ =='__main__':
a= outer()
a() //輸出1
a() //輸出2
裝飾器就是通過閉包來給原有函數(shù)增加新功能。例如我們通過給調(diào)用函數(shù)增加顯示調(diào)用次數(shù)的功能。
def outer(func):
count= [0]
def inner(a,b):
count[0] +=1
print(count[0])
return func(a,b)
return inner
def add(a,b):
print("a + b value is %s" % (a+b))
return
if __name__ =='__main__':
a= outer(add)
a(2,3)
//1
// a + b value is 5
a(3,4)
//2
//a + b value is 7
a = outer(add),則def outer(func)中的func = add
outer函數(shù) 返回的是內(nèi)部函數(shù)的引用,所以a = inner(a,b)
inner函數(shù)返回的為func(a,b),所以 a= add(a,b)
在inner return func(a,b)前可以增加任意操作喲。
有些人認(rèn)為這樣a = outer(add) 不美觀,所以引用了語法糖,在需要添加功能的函數(shù)前加上 @outer 即可:
def outer(func):
count= [0]
def inner(a,b):
count[0] +=1
print(count[0])
return func(a,b)
return inner
@outer
def add(a,b):
print("a + b value is %s" % (a+b))
return
if __name__ =='__main__':
add(2,3)
//1
// a + b value is 5
add(3,4)
//2
//a + b value is 7