裝飾器的調用時機是在導入時,或者是加載時就執行,如下代碼:
register = []
def regester(func):
print 'running regisster ({0})'.format(func)
register.append(func)
return func
@regester
def f1():
print "running f1()"
@regester
def f2():
print "running f2()"
def f3():
print "running f3()"
def main():
print "running main()"
print register
f1()
f2()
f3()
其執行結果如下:
running regisster (<function f1 at 0x1035ae5f0>)
running regisster (<function f2 at 0x1035ae668>)
running main()
[<function f1 at 0x1035ae5f0>, <function f2 at 0x1035ae668>]
running f1()
running f2()
running f3()
按照正常的代碼執行邏輯要執行,那麼第一個打印出來的應該是"running main()"
,但是實際上在第三行才打出來了,前面兩行都是裝飾器裡面的內容,用Debug模式來運行,看的比較清楚。
如圖所示,我在運行初識的時候打了一個端點,Debug模式運行後,程序已經打印出了裝飾器的內容。
——以上來自《流暢的Python》
之前一直有用過這塊,不過遇到了一點問題,在修飾類裡面的函數時,經常會出現參數錯誤的情況,因為類裡面的函數第一個參數總是self
,在執行的時候經常保參數不正確,這裡分享一個我實踐成功的一個裝飾器函數,可以解決這個問題。
# ecoding=utf-8
# Author: 翁彥彬 | Sven_Weng
# Email : [email protected]
# Web : http://wybblog.applinzi.com
import time
import functools
def log(func):
@functools.wraps(func)
def inner_methods(*args, **kwargs):
t0 = time.time()
result = func(*args, **kwargs)
t1 = time.time()
name = func.__name__
arg_list = []
if args:
arg_list.append(', '.join([str(arg) for arg in args]))
if kwargs:
pairs = ['{0}={1}'.format(k, w) for k, w in sorted(kwargs.items())]
arg_list.append(', '.join(pairs))
print "[{0}]func_name:{1},args:({2})".format(str(t1 - t0), name, arg_list)
return result
return inner_methods
這個裝飾器裝飾之後,會把執行的函數名,入參和執行的時間全部都打出來。