在Python中一切皆對象,函數是一等對象。這意味着可以通過名字引用函數。
1
2
3
4
5
6
7
8
9
10
11
12
13
<code>>>> a=123</code>
<code>>>> a</code>
<code>123</code>
<code>>>> name=</code><code>'zeng'</code>
<code>>>> name</code>
<code>'zeng'</code>
<code>>>> def func():</code>
<code>... print </code><code>"hello!"</code>
<code>...</code>
<code>>>> func</code>
<code><</code><code>function</code> <code>func at 0x1066bdc08></code>
<code>>>> func()</code>
<code>hello!</code>
從上面的例子可以看出,調用函數時隻需要函數名後面加‘()’即可。如果不加,則傳回函數記憶體位址。
函數還可以作為值傳遞
<code>>>> dict = {</code><code>'func'</code><code>:func}</code>
<code>>>> aaa = dict[</code><code>'func'</code><code>]</code>
<code>>>> aaa</code>
<code>>>> aaa()</code>
從上面的例子可以看到,函數可以作為值儲存到字典dict的‘func’這個key中。然後将函數這個值又可以指派給變量aaa,當執行aaa時,傳回的是函數的記憶體位址,如果調用函數則執行aaa()
函數可以作為值傳遞,那麼是否可以作為參數傳遞呢?
<code>>>> def func1():</code>
<code>... </code><code>return</code> <code>"I am an amazing function"</code>
<code>>>> def printer(arg):</code>
<code>... print </code><code>"The function passwd to me says:"</code> <code>+ arg()</code>
<code>>>> printer(func1)</code>
<code>The </code><code>function</code> <code>passwd</code> <code>to me says:I am an amazing </code><code>function</code>
<code>>>></code>
從上面的例子可以看到,函數完全可以作為參數傳遞。而且傳遞給函數的函數還可以被調用
裝飾器的基礎:
本質上裝飾器就是一個以另一個函數作為參數的函數。看下面的例子:
上面的例子中當執行decorated_function()時,調用了decorated_function函數,而
decorated_function = identity_decorator(a_function),是以調用decorated_function()函數,實際上就是調用了 identity_decorator( )函數。而 identity_function( )函數傳回的是wrapper( )函數的記憶體位址。是以調用 identity_decorator( )函數最終會調用wrapper( )函數,而wrapper( )函數則是調用了
identity_decorator(func)函數的參數。這個參數本身就是a_function()函數,是以最終結果是調用了a_function()函數,輸出結果就是a_function()的輸出結果。
那麼問題來了,上面這個例子饒了一大圈,結果就是調用了a_function()函數,那麼完全可以直接調用a_function()函數,何必兜一圈子呢,是以上面這個例子是一個沒有意義的裝飾器。
下面看一個有意義的裝飾器
上面代碼中@login是裝飾器的寫法。意思是将@login下面的函數作為login()函數的參數。也可以這樣寫
buy = login(buy)
當執行@login時,實際上就是執行了buy = login(buy)
意思是将buy函數作為參數調用login函數,并将結果指派給buy這個變量中。而login函數傳回的是inner函數的記憶體位址。是以當執行buy('zeng')時,其實是調用inner函數,此時會執行
執行func(arg),則實際上是執行login函數的參數這個函數,這個函數就是buy函數,是以此時會調用buy函數,并将‘zeng’這個參數傳遞到buy函數中,是以結果就是既執行了inner函數,又執行了buy函數。
本文轉自 曾哥最愛 51CTO部落格,原文連結:http://blog.51cto.com/zengestudy/1828019,如需轉載請自行聯系原作者