上一篇文章我們對(duì)裝飾器有了初步了解拳缠,接下來(lái)開始是對(duì)裝飾器的進(jìn)一步實(shí)踐
1.少了元信息怎么辦
當(dāng)你寫了一個(gè)裝飾器作用在某個(gè)函數(shù)上,但是這個(gè)函數(shù)的重要的元信息比如名字惜纸、文檔字符串套硼、注解和參數(shù)簽名都丟失了兵钮。這到底是怎樣的一種現(xiàn)象呢?直接上代碼吧钠右。
# -*- coding:UTF-8 -*-
def show_me(func):
def wrapper():
print "It is in wrapper."
func()
return wrapper
@show_me
def func1():
'''
this is func1
'''
print "running func1"
if __name__ == '__main__':
func1()
print func1.__name__
print func1.__doc__
打印結(jié)果:
我們可以看到func1.__name__
輸出為wrapper
赋元,func1.__doc__
輸出為None
,哇飒房,全亂套了搁凸,怎么辦。不要怕狠毯,Python
大法自有辦法护糖。
溫馨提醒:任何時(shí)候你定義裝飾器的時(shí)候,都應(yīng)該使用 functools 庫(kù)中的
@wraps
裝飾器來(lái)注解底層包裝函數(shù)。
也就是說(shuō)嚼松,裝飾器函數(shù)應(yīng)該這樣做補(bǔ)充:
from functools import wraps ##導(dǎo)入這個(gè)包
def show_me(func):
@wraps(func)
def wrapper():
print "It is in wrapper."
func()
return wrapper
加上這個(gè)后嫡良,你可以再運(yùn)行一下,應(yīng)該會(huì)得到完整的元數(shù)據(jù).
2.被裝飾函數(shù)有參數(shù)
我們可以看到献酗,上文的被裝飾函數(shù)(也就是func
函數(shù))是沒(méi)有參數(shù)的寝受,但是在實(shí)際應(yīng)用中,我們大多數(shù)的函數(shù)都會(huì)有參數(shù)罕偎,這就要用到Python
中的可變參數(shù)了很澄。那么對(duì)于被裝飾函數(shù)帶有參數(shù)的裝飾器該怎么寫呢,可見如下代碼:
# -*- coding:UTF-8 -*-
from functools import wraps
def show_me(func):
@wraps(func)
def wrapper(*args, **kwargs):
print "強(qiáng)哥好帥!"
return func(*args, **kwargs)
return wrapper
@show_me
def func4(a, b=2):
print "a = %s"%a
print "b = %s"%b
if __name__ == '__main__':
func4(3, 8)
運(yùn)行結(jié)果如下:
>>強(qiáng)哥好帥!
>>a = 3
>>b = 8
可變參數(shù)是個(gè)好東西,在Python
中(星號(hào))*
和參數(shù)有許多有趣的用法甩苛,值得一看忙干。
3.裝飾器帶有參數(shù)
有時(shí)候,@
語(yǔ)法糖后面還可以帶參數(shù)浪藻。比如某個(gè)函數(shù)功能只有擁有經(jīng)理權(quán)限的人才能訪問(wèn)∏瑁可以編寫這樣的一個(gè)裝飾器@has_permission("manager")
,下面來(lái)舉一個(gè)簡(jiǎn)單粗魯?shù)睦踝樱?/p>
# -*- coding:UTF-8 -*-
from functools import wraps
def has_permission(position=""):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if position == "manager":
print "我是經(jīng)理我怕誰(shuí)!"
return func(*args, **kwargs)
else:
print "You don not have permission to access!"
return wrapper
return decorator
@has_permission(position="manager")
def func5(name=""):
print "My name is : %s"%name
if __name__ == '__main__':
func5("zhujq")
結(jié)果為:
>>我是經(jīng)理我怕誰(shuí)!
>>My name is : zhujq
當(dāng)position
改為其他時(shí)(比如“Boss”
)皂甘,程序便只能輸出:
You don not have permission to access!
4.其他
Python
還提供了類裝飾器與@staticmethod
嗡官,@classmethod
,@property
和這三個(gè)在面向?qū)ο缶幊讨谐S玫难b飾器,我們下次再講吧~~