【python學習筆記】Python裝飾器

裝飾器是什麼意思

一個大牛舉的例子:
內褲可以用來遮羞,但是到了冬天它沒法爲我們防風禦寒,聰明的人們發明了長褲,有了長褲後寶寶再也不冷了,裝飾器就像我們這裏說的長褲,在不影響內褲作用的前提下,給我們的身子提供了保暖的功效。

裝飾器本質上是Python函數,可以爲已存在的對象添加額外的功能,同時裝飾器還可以抽離出與函數無關的重用代碼。具體應用場景如:插入日誌、性能測試、事務處理、緩存、權限校驗等。

舉個栗子

需要在某個原有功能上加一層驗證

def a():
    print 'a'

def b():
    print 'a'

a b 方法很多地方調用,不想更改原有調用方式

即:

def a():
    權限驗證
    print 'a'

def b():
    權限驗證
    print 'a'

假如有很多的接口—-

用裝飾器來實現:

def auth(func):
    def inner():
        # 驗證1
        return func()
    return inner

@auth
def a():
    print 'a'
@auth
def a():
    print 'b'

帶參數裝飾器

執行方法帶參數

def auth(func):
    def inner(arg1,arg2):
        # 驗證1
        return func(arg1,arg2)
    return inner

@auth
def a(arg1,arg2):
    print 'a'
@auth
def b(arg1,arg2):
    print 'b'

裝飾器帶參數

def auth(info):
    def decorator(func):
        def inner(arg1,arg2):
            # 驗證1
            print info
            return func(arg1,arg2)
        return inner
    return decorator



@auth(info='a')
def a(arg1,arg2):
    print 'a'
@auth(info='b')
def b(arg1,arg2):
    print 'b'

類裝飾器

再來看看類裝飾器,相比函數裝飾器,類裝飾器具有靈活度大、高內聚、封裝性等優點。使用類裝飾器還可以依靠類內部的__call__方法,當使用 @ 形式將裝飾器附加到函數上時,就會調用此方法。

class Foo(object):     
    def __init__(self, func):     
    self._func = func  
def __call__(self):     
    print ('class decorator runing')     
    self._func()    
    print ('class decorator ending')  
@Foo 
def bar():    
    print ('bar')  bar()

裝飾器執行順序

@a
@b
@c
def f ():

等於

f = a(b(c(f)))

帶來的問題(知乎劉志軍大牛)

使用裝飾器極大地複用了代碼,但是他有一個缺點就是原函數的元信息不見了,比如函數的docstring、name、參數列表

這個問題就比較嚴重的,好在我們有functools.wraps,wraps本身也是一個裝飾器,它能把原函數的元信息拷貝到裝飾器函數中,這使得裝飾器函數也有和原函數一樣的元信息了。

from functools import wraps 
def logged(func):     
    @wraps(func)     
    def with_logging(*args, **kwargs):         
        print func.__name__ + " was called"         
        return func(*args, **kwargs)     
    return with_logging 
@logged 
def f(x):     
    """does some math"""     
    return x + x * x  
print f.__name__  # prints 'f' 
print f.__doc__   # prints 'does some math'

leason | blog

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章