Python進階(六)-python編寫無引數decorator
分享一下我的偶像大神的人工智慧教程!http://blog.csdn.net/jiangjunshow
也歡迎轉載我的文章,轉載請註明出處 https://blog.csdn.net/mm2zzyzzp
Python進階(六)-python編寫無引數decorator
Python的 decorator 本質上就是一個高階函式,它接收一個函式作為引數,然後,返回一個新函式。
使用 decorator 用Python提供的 @ 語法,這樣可以避免手動編寫 f = decorate(f) 這樣的程式碼。
考察一個@log的定義:
def log (f):
def fn(x):
print 'call ' + f.__name__ + '()...'
return f(x)
return fn
- 1
- 2
- 3
- 4
- 5
對於階乘函式,@log工作得很好:
@log
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
- 1
- 2
- 3
- 4
結果:
call factorial()…
3628800
但是,對於引數不是一個的函式,呼叫將報錯:
@log
def add(x, y):
return x + y
print add(1, 2)
- 1
- 2
- 3
- 4
結果:
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
- 1
- 2
- 3
- 4
- 5
現在,對於任意函式,@log 都能正常工作。
舉例
請編寫一個@performance,它可以打印出函式呼叫的時間。
計算函式呼叫的時間可以記錄呼叫前後的當前時間戳,然後計算兩個時間戳的差。
參考程式碼:
import time
def performance(f):
def fn(*args, **kw):
t1 = time.time()
r = f(*args, **kw)
t2 = time.time()
print 'call %s() in %fs' % (f.__name__, (t2 - t1))
return r
return fn
@performance
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
分享一下我的偶像大神的人工智慧教程!http://blog.csdn.net/jiangjunshow
也歡迎轉載我的文章,轉載請註明出處 https://blog.csdn.net/mm2zzyzzp