python 裝飾器功能以及函式引數使用介紹

NO IMAGE

簡單的說:裝飾器主要作用就是對函式進行一些修飾,它的出現是在引入類方法和靜態方法的時候為了定義靜態方法出現的。例如為了把foo()函式宣告成一個靜態函式
複製程式碼 程式碼如下:
class Myclass(object):
def staticfoo():
…………
…………
staticfoo = staticmethod(staticfoo)

可以用裝飾器的方法實現:
複製程式碼 程式碼如下:
class Myclass(object):
  @staticmethod  
  def staticfoo():
    ………
    ………

這個例子很明顯很容易就可以看懂。

說到這裡我們舉一個下面的例子,這個例子裡面同時涉及到一個重要內容,就是對於python中的函式的本質理解。

程式碼:
複製程式碼 程式碼如下:
# -*- coding: utf-8 -*-
from time import ctime
from time import sleep
def ftfunc(func):
def timef():
print “[%s] %s() called” % (ctime(),func.__name__)
return func()
return timef

@ftfunc
def foo():
print ‘hello’

if __name__ == ‘__main__’:

foo()
sleep(2)

for i in range(2):
sleep(1)
foo()

執行這段程式碼;我們可以看到終端依次會輸出以下內容:


其中ftfunc函式是我們自己自定義的一個函式,這個函式是以一個函式作為引數的函式,這也就滿足了作為一個裝飾器的要求,根據上面我們對於裝飾器的等價變換規則,這段程式碼
複製程式碼 程式碼如下:
@ftfunc
def foo():
print ‘hello’

可以轉換成以下的程式碼:
複製程式碼 程式碼如下:
def foo():
print ‘hello’

foo = ftfunc(foo)

再結合上面原來的程式碼我們很快就可以體會到了裝飾器的作用。

但是我在編寫這段程式碼的時候,有一個地方打錯了:

這段程式碼:
複製程式碼 程式碼如下:
return func()
return timef

被我寫成了:
複製程式碼 程式碼如下:
return func
return timef

於是輸出結果就是不一樣,後來終於發現了一個重要的概念:”foo”是函式物件的引用,而”foo()”是函式物件的呼叫。關於物件引用是python的重要的基礎概念,在python中一切都是物件,同時型別是屬於物件,而不是變數。一切的變數只是物件的引用,相當於讓這個變數指向這個物件。“foo”正好可以理解成一個變數,只不過是它指向一個函式的物件。而“foo()”是函式物件的呼叫,即呼叫這個物件,是要執行這個函式的功能的。這裡需要慢慢理解品味。基於此:

這樣的一段程式碼執行結果和剛才是一模一樣的。注意比較與剛才那段程式碼的不同之處,更加有利於理解。
複製程式碼 程式碼如下:
# -*- coding: utf-8 -*-
from time import ctime
from time import sleep
def ftfunc(func):
def timef():
print “[%s] %s() called” % (ctime(),func.__name__)
return func
return timef

@ftfunc
def foo():
print ‘hello’

if __name__ == ‘__main__’:

foo()()
sleep(2)

for i in range(2):
sleep(1)
foo()()

此程式碼執行結果:

其實還可以分別對返回的timef函式加上括號,看看結果會是怎麼樣的。可以更好理解python中函式的概念。

您可能感興趣的文章:

Python中的各種裝飾器詳解Python中的裝飾器用法詳解詳解Python中的裝飾器、閉包和functools的教程python重試裝飾器示例Python中的多重灌飾器詳解Python裝飾器由淺入深Python裝飾器decorator用法例項例項講解Python程式設計中@property裝飾器的用法Python自動重試HTTP連線裝飾器Python裝飾器原理與簡單用法例項分析