python裝飾器應(yīng)該算是面試常考到的用點(diǎn)鄙才,之前在flask的應(yīng)用中也是會(huì)常常用到悼院,抽空仔細(xì)看書查資料理解了下裝飾器的概念,通過自己的理解記憶咒循,應(yīng)該對(duì)這個(gè)概念會(huì)有一個(gè)大致上具體的了解据途。
閉包
說起python裝飾器,我們應(yīng)該不得不談?wù)勯]包的概念叙甸。
我對(duì)閉包的理解是颖医,當(dāng)函數(shù)存在嵌套,子函數(shù)調(diào)用了父函數(shù)的變量裆蒸,那么子函數(shù)體加上父函數(shù)中調(diào)用的變量熔萧,那么這時(shí)候子函數(shù)加上這個(gè)調(diào)用的變量,就形成了一個(gè)閉包僚祷。如果子函數(shù)沒有調(diào)用父函數(shù)的變量佛致,那么就不存在閉包。我們可以來看一段代碼:
In [7]: def fun1():
...: a,b,c = 1,2,3
...: def fun2():
...: x = 1
...: return x+a
...: return fun2
...:
In [8]: foo = fun1()
In [9]: foo()
Out[9]: 2
在這里辙谜,fun2
和fun1
中的a
形成了一個(gè)閉包俺榆。每次調(diào)用父函數(shù)中的值的時(shí)候,就會(huì)產(chǎn)生一個(gè)新的閉包装哆,如果我這里用的是b
或者c
罐脊,那么會(huì)產(chǎn)生不一樣的閉包。
我們可以發(fā)現(xiàn)蜕琴,在這里萍桌,我們傳遞的是一個(gè)整數(shù)。當(dāng)我們傳遞的是一個(gè)函數(shù)的時(shí)候凌简,那么就成了一個(gè)裝飾器上炎。裝飾器的本質(zhì)就是函數(shù)閉包,利用了函數(shù)閉包的特性
裝飾器
In [3]: def decorator(func):
...: def wrapped():
...: print "{} is running".format(func.__name__)
...: return func()
...: return wrapped
...:
In [4]: def foo():
...: print "I'm the function"
...:
In [5]: wrapped_func = decorator(foo)
In [6]: wrapped_func()
foo is running
I'm the function
在這里decorator
就是裝飾器雏搂,它將func
包裝起來這里的代碼相當(dāng)繁瑣藕施,這時(shí)候我們可以用python的語法糖來進(jìn)行修飾@
。代碼如下
In [9]: @decorator
...: def bar():
...: print "I'm the guy"
...:
In [11]: bar()
bar is running
I'm the guy
這里只是簡(jiǎn)單的裝飾器的用法畔派,后續(xù)還會(huì)討論分析其他的用法