python中編寫無引數decorator

2022-06-23 23:15:18 字數 1560 閱讀 1503

python的 decorator 本質上就是一個高階函式,它接收一個函式作為引數,然後,返回一個新函式。

使用 decorator 用python提供的 @ 語法,這樣可以避免手動編寫 f = decorate(f) 這樣的**。

考察一個@log的定義:

def

log(f):

deffn(x):

print

'call

' + f.__name__ + '

()...

'return

f(x)

return fn

對於階乘函式,@log工作得很好:

@log

deffactorial(n):

return reduce(lambda x,y: x*y, range(1, n+1))

print factorial(10)

結果:

call factorial()...

3628800

但是,對於引數不是一個的函式,呼叫將報錯:

@log

defadd(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,保證任意個數的引數總是能正常呼叫:

def

log(f):

def fn(*args, **kw):

print

'call

' + f.__name__ + '

()...

'return f(*args, **kw)

return fn

現在,對於任意函式,@log 都能正常工作。

練習:編寫一個@performance,它可以列印出函式呼叫的時間

import

time

defperformance(f):

a =time.time()

def fn(*argc, **kw):

print f(*argc, **kw)

print time.time() -a

return

[email protected]

deffactorial(n):

return reduce(lambda x,y: x*y, range(1, n+1))

print factorial(10)

結果:

3628800

0.0189998149872none