裝飾器主要是用來包裝函式,對於一些常用的功能,譬如:日誌列印,函式計時,身份認證。我們可以使用裝飾器來實現,這樣可以降低整個程式的複雜度和減少程式的**量。
它實際上就是函式,不同的是,它把乙個函式當做引數,然後返回乙個替代版函式。
下面看乙個簡單的示例:
defadd_number(func):defadder(arg):return func(arg)+100
returnadderdeff(x):returnx
f=add_number(f)print f(20)
add_number就是乙個裝飾器函式,它接受乙個函式(f)作為引數,然後返回另外乙個函式(adder)賦值給原來的函式,這樣,原來的函式不用新新增額外的**量而實現了加法的功能。
這個就是裝飾器的原始實現。
but,這種方式還是有點不太方便,畢竟還是繞了一圈,用f=add_number(f)來給原來的函式重新賦值。
其實,python中可以用下列方式來簡化對於裝飾器的引用。
defadd_number(func):defadder(arg):return func(arg)+100
returnadder
@add_numberdeff(x):returnxprint f(20)
只需乙個簡單的@add_numbe呼叫,是不是方便,簡單了很多,基本上沒侵入原來的**。
有,python提供了乙個decorator包,可以大大簡化裝飾器的書寫。
so,第三種實現方式為:
from decorator importdecorator
喔,果然更加簡單了~
以上示例接受的都是乙個引數,其實,函式本身是可以接受可變引數的。
如:return f(arg1,*args,**kwargs)
args=('joy','steve')
kwargs=
f('china',*args,**kwargs)
輸出結果為:
non-keyword arg: joy
non-keyword arg: steve
keyword arg: age:20
關於*args,**kwargs的區別,兩者都可用於表示可變長度的引數。只不過前者是用元祖表示,沒有key值,後者是字典,有key值。兩者可用於在同乙個函式中,但是,*args必須出現在**kwargs之前。
譬如下例:
deftest_var_args_call(arg1, arg2, arg3):print "arg1:", arg1print "arg2:", arg2print "arg3:", arg3
args=(1,2,3)
kwargs=
test_var_args_call(*args)print '-----------------'test_var_args_call(**kwargs)
兩者的實現效果一樣。
最後來個示例,通過顯示函式執行的時間來裝飾乙個函式
@logdeffoo():pass
for i in range(4):
foo()
time.sleep(1)
輸出結果如下:
[wed jul 27 09:17:23 2016] foo() was called...
[wed jul27 09:17:24 2016] foo() was called...
[wed jul27 09:17:25 2016] foo() was called...
[wed jul27 09:17:26 2016] foo() was called...
python裝飾器 Python 裝飾器
簡言之,python裝飾器就是用於拓展原來函式功能的一種函式,這個函式的特殊之處在於它的返回值也是乙個函式,使用python裝飾器的好處就是在不用更改原函式的 前提下給函式增加新的功能。一般而言,我們要想拓展原來函式 最直接的辦法就是侵入 裡面修改,例如 這是我們最原始的的乙個函式,然後我們試圖記錄...
python核心裝飾 python核心 裝飾器
ython有著強大的表示式語法和函式特性,其中乙個我的最愛便是裝飾器。在設計模式中,裝飾器能夠在不使用子類的情況下動態的修改函式 方法或類的功能。當你需要擴充套件某個函式的功能卻不想直接修改這個函式的時候,裝飾器就可以派上用場了。實現裝飾器模式有很多種方法,但是python通過強大的語法支援來讓這個...
python 函式裝飾 Python 函式裝飾器
無引數的 函式裝飾器 funa 作為裝飾器函式 def funa fn print sakura func a fn 執行傳入的fn引數 print sakura second return sakura return funa def funb print sakurab 返回結果為 sakura...