- 版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 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...