通俗點說,裝飾器就是乙個返回值是函式的函式,這麼說可能有點繞。
仔細分解:
1.首先它是函式
2.它的返回值是乙個函式
裝飾器是乙個返回函式的函式(默讀三十遍 _ ),那麼它的作用是什麼呢?還是一句話描述的話:用於增強其他已存在函式的功能!目的是在不改變原函式名(類名)的情況下,給函式增加新的功能。
先來點前奏:正常情況下當我們想要拓展原來的函式功能時,最直接的方式就是改動函式(以前我也這麼想),但是現實卻不是這樣的,人家函式辛辛苦苦寫的好好的,你去改它萬一出問題了誰能負責呢?所以這是萬萬不能改滴。因此,這也就出現了裝飾器,上菜:
# 函式fun1如下所示,現在我們想要看一下這個函式執行的總時間(不能改動這個**)
deffun1
(num1,num2)
: time.sleep(10)
print
(num1+num2)
# 既然不能改動這個函式,那麼只能自己再定義個函式咯
defdeco
(func)
:# 這個func其實就是乙個函式,如果我們在fun1函式上加@deco這個裝飾器,這個func就是fun1
def():
start_time = time.time(
) func(
)# 這裡就是呼叫了func方法
end_time = time.time(
) execution_time = end_time - start_time
print
(execution_time)
像上面這樣,deco就是乙個裝飾器,fun1就是乙個函式。
當我們在fun1函式上面加上deco這個裝飾器的話,就意味著將fun1傳遞給deco這個裝飾器。
實際上就是在呼叫fun1這個方法時就是呼叫了deco(fun1)這個函式,也就是fun1 = deco(fun1)了
# 加上裝飾器的函式
@deco
deffun1
(num1,num2)
: time.sleep(10)
print
(num1+num2)
# 裝飾器
defdeco
(func)
:# 這個func其實就是乙個函式,如果我們在fun1函式上加@deco這個裝飾器,這個func就是fun1
def():
start_time = time.time(
) func(
)# 這裡就是呼叫了func方法
end_time = time.time(
) execution_time = end_time - start_time
print
(execution_time)
所以當我們在呼叫fun1這個函式的時候,其實就是呼叫了deco(fun1)這個函式那麼,當有兩個裝飾器裝飾乙個函式的時候是什麼情況呢?
def
deco01
(f):
def(
*args,
**kwargs)
:print
("this is deco01"
) start_time = time.time(
) f(
*args,
**kwargs)
end_time = time.time(
) execution_time =
(end_time - start_time)
*1000
print
("time is %d ms"
% execution_time)
print
("deco01 end here"
)def
deco02
(f):
def(
*args,
**kwargs)
:print
("this is deco02"
) f(
*args,
**kwargs)
print
("deco02 end here"
)@deco01
@deco02
deff
(a,b)
:print
("be on"
) time.sleep(1)
print
("result is %d"
%(a+b)
)# this is deco01
# this is deco02
# be on
# result is 7
# deco02 end here
# time is 1000 ms
# deco01 end here
# 對於python中的」@」語法糖,裝飾器的呼叫順序與使用 @ 語法糖宣告的順序相反。
# 在這個例子中,」f(3, 4) = deco01(deco02(f(3, 4)))」。
# 先執行deco1,再執行deco2,deco2在deco1裡面執行
python內建有三個裝飾器,分別是@property,@staticmethod,@classmethod都是和class有關
其作用:
@property:將某函式,作為屬性使用
class
animal()
: @property
deffun1
(self)
:return self.value
@fun1.setter
deffun1
(self,value)
: self.value = value
@property
deffun2
(self)
:print
("nihao"
)if __name__==
"__main__"
: animal.fun1 =
9# 這裡相當於是給value賦值了,呼叫了@fun1.setter函式
print animal.fun1 # 呼叫@property函式
animal.fun2
#總結:就是將方法當作乙個屬性來使用,並且可以賦值
@classmethod:類方法,直接通過類名.方法名進行呼叫
classa(
):@classmethod
deffun1
(cls,x,y)
:return x*y
deffun2
(self,x,y)
:return x*y
if __name__=
"__main__"
:print a.func1(1,
2)# 直接呼叫,不要例項化物件
print a(
).fun2(1,
2)
@staticmethod 靜態,將方法靜態化,直接可以用類.方法來呼叫
classa(
):@staticmethod
deffun1
(x,y)
:return x*y
deffun2
(self,x,y)
:return x*y
if __name__=
"__main__"
:print a.func1(1,
2)# 直接呼叫,不要例項化物件
print a(
).fun2(1,
2)
裝飾器的理解就是這麼多,總結而言就是兩句話:
1.裝飾器是乙個返回值是函式的函式
2.裝飾器的目的是為了給已存在的函式增強功能
python裝飾器介紹 Python之裝飾器簡介
python函式式程式設計之裝飾器 1.開放封閉原則 簡單來說,就是對擴充套件開放,對修改封閉。在物件導向的程式設計方式中,經常會定義各種函式。乙個函式的使用分為定義階段和使用階段,乙個函式定義完成以後,可能會在很多位置被呼叫。這意味著如果函式的定義階段 被修改,受到影響的地方就會有很多,此時很容易...
python的裝飾器 property介紹
今天介紹一下python的裝飾器,先看乙個例子 import traceback class screen object property def width self return self.width width.setter def width self,width if isinstance...
介紹Python的 property裝飾器的用法
在繫結屬性時,如果我們直接把屬性暴露出去,雖然寫起來很簡單,但是,沒辦法檢查引數,導致可以把成績隨便改 s student s.score 9999 這顯然不合邏輯。為了限制score的範圍,可以通過乙個set score 方法來設定成績,再通過乙個get score 來獲取成績,這樣,在set s...