1. 程式人生 > >Python進階(六)-python編寫無引數decorator

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