天天看點

python裝飾器補充之functools包中的wraps

  • 版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/kun1280437633/article/details/80315895

Python裝飾器(decorator)在實作的時候,有一些細節需要被注意。例如,被裝飾後的函數其實已經是另外一個函數了(函數名等函數屬性會發生改變)。這樣有時候會對程式造成一些不便,例如筆者想對flask架構中的一些函數添加自定義的decorator,添加後由于函數名和函數的doc發生了改變,對測試結果有一些影響。

是以,Python的functools包中提供了一個叫wraps的decorator來消除這樣的副作用。寫一個decorator的時候,最好在實作之前加上functools的wrap,它能保留原有函數的名稱和docstring。

# 未加裝飾器代碼

def test1():

    '''test1...'''

    print('test1')

def test2():

    '''test2...'''

    print('test2')

print (test1.__name__)

print (test1.__doc__)

print (test2.__name__)

print (test2.__doc__)

# 結果:

test1

test1...

test2

test2...

# 加裝飾器未加wraps代碼:

# coding:utf8

from functools import wraps

def login_required(view_func):

    def wrapper(*args,**kwargs):

        pass

    return wrapper

@login_required

def test1():

    '''test1...'''

    print('test1')

@login_required

def test2():

    '''test2...'''

    print('test2')

print (test1.__name__)

print (test1.__doc__)

print (test2.__name__)

print (test2.__doc__)

#結果:

wrapper

None

wrapper

None

# 加裝飾器加wraps代碼:

# coding:utf8

from functools import wraps

def login_required(view_func):

    @wraps(view_func)

    def wrapper(*args,**kwargs):

        pass

    return wrapper

@login_required

def test1():

    '''test1...'''

    print('test1')

@login_required

def test2():

    '''test2...'''

    print('test2')

print (test1.__name__)

print (test1.__doc__)

print (test2.__name__)

print (test2.__doc__)

結果:

test1

test1...

test2

test2...