python的 decorator 本質上就是乙個高階函式,它接收乙個函式作為引數,然後,返回乙個新函式。
使用 decorator 用python提供的 @ 語法,這樣可以避免手動編寫 f = decorate(f) 這樣的**。
考察乙個@log的定義:
deflog(f):
deffn(x):
'call
' + f.__name__ + '
()...
'return
f(x)
return fn
對於階乘函式,@log工作得很好:
@logdeffactorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
結果:
call factorial()...3628800
但是,對於引數不是乙個的函式,呼叫將報錯:
@logdefadd(x, y):
return x +y
print add(1, 2)
結果:
traceback (most recent call last):file
"test.py
", line 15, in
print add(1,2)
typeerror: fn() takes exactly 1 argument (2 given)
因為 add() 函式需要傳入兩個引數,但是 @log 寫死了只含乙個引數的返回函式。
要讓 @log 自適應任何引數定義的函式,可以利用python的 *args 和 **kw,保證任意個數的引數總是能正常呼叫:
deflog(f):
def fn(*args, **kw):
'call
' + f.__name__ + '
()...
'return f(*args, **kw)
return fn
現在,對於任意函式,@log 都能正常工作。
練習:編寫乙個@performance,它可以列印出函式呼叫的時間
importtime
defperformance(f):
a =time.time()
def fn(*argc, **kw):
print f(*argc, **kw)
print time.time() -a
return
fn@performance
deffactorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
結果:
36288000.0189998149872none
Python的帶引數和無引數decorator
python的decorator,有帶引數和無引數兩種,帶引數的decorator採用了三層巢狀,使用 decorator 用python提供的 語法,這樣可以避免手動編寫 f decorate f 這樣的 無參的decorator import time def performance f def...
python中引數 Python中的引數
python中的引數 1.python函式引數有多重形式 test arg1,arg2,args test arg1,arg2,args kwargs 2.其中比較糊弄人的是 args和 kwargs args 變長的佔位引數列表 kwargs 變長的鍵值對引數列表 3.什麼是佔位引數 test a...
python中的引數 python中的引數
一 位置引數 def test x,y print x print y test 1,2 與形參一一對應 結果如下 二 關鍵字引數 def test1 x,y print x print y test1 y 2,x 3 與形參順序無關 結果如下 三 預設引數 def student name,age...