當我們做好乙個產品之後,需要對它進行不斷地維護,對某些函式增加一些功能。這個時候如果去修改源**將是非常不合適的。(原因:1.原則上已經寫好的函式盡量不去修改它,因為一旦修改可能會導致不可預知的錯誤發生或者降低穩定性。2.函式可能被呼叫很多很多次,如果修改函式有可能會導致呼叫方式發生改變,會有大量的修改工作。)所以,裝飾器就出現了。它可以做到為函式增添新功能的同時而不修改函式本身的源**。
1.不能修改被修飾函式的源**
2.不能修改被修飾函式的呼叫方式
1.函式即「變數」:定義乙個函式,相當於將函式體賦值給函式名這個變數。
2.高階函式:滿足以下兩個條件之一的函式即為高階函式:①把函式名當做實參傳給另乙個函式②返回值中包含函式名
3.巢狀函式:函式是可以巢狀的
高階函式+巢狀函式=裝飾器
裝飾器的本質是函式,功能是為其它函式新增附加功能
#可以寫裝飾器:現在有兩個函式,分別有各自的功能,需求是計算每個函式執行的時間
deftext1():
time.sleep(2)
print("
this is text1")
def text2(*args,**kwargs):
time.sleep(2)
print("
this is text2
",args[0],args[1])
def其中func()函式是原函式真正的執行過程,deco函式內其他的語句都是新新增功能的語句timer(func):
def deco(*args,**kwargs):
start_time=time.time()
func(*args,**kwargs)
end_time=time.time()
print("
the function tun time is
".format(end_time-start_time))
return deco
裝飾器名叫timer
寫好裝飾器就行了嗎?不是,還差乙個步驟,在原函式上方增加一條語句,整合到一起:
def裝飾器解析:deco函式用來實現新增功能,timer函式和@timer語句用來使呼叫方式不發生改變timer(func):
def deco(*args,**kwargs):
start_time=time.time()
func(*args,**kwargs)
end_time=time.time()
print("
the function tun time is
".format(end_time-start_time))
return
deco
@timer
#此操作的作用是將裝飾器的功能加到原函式上 相當於text1=timer(text1)
deftext1():
time.sleep(2)
print("
this is text1")
@timer
#沒有@timer語句則不會將裝飾器功能加上
def text2(*args,**kwargs): #
如果原函式有引數,需要在裝飾器中deco上加引數
time.sleep(2)
print("
this is text2
",args[0],args[1])
text1()
#不改變呼叫方式,且增加了新功能
text2(29000,"
hello
")
執行結果:
這裡說的不是原函式帶引數,而是裝飾器函式本身帶引數
現在有需求,用裝飾器實現登陸過程,並且有兩種不同的登陸方式:使用本地資料登陸和使用雲端資料登陸
#需要裝飾器:現在有三個網頁,其中登陸home時用本地資料,登陸bbs時用雲端資料
defindex():
print("
welcome to index page")
defhome():
print("
welcome to home page")
return
"form home
"def
bbs():
print("
welcome to bbs page
")
name="其實就是將原來的裝飾器外層又巢狀了一層函式,用來傳遞引數。@語句也變成了@auth(auth_type=" ")alex
"word="
123"
defauth(auth_type):
defauth_out(func):
def deco(*args,**kwargs):
if auth_type=="
local
": #
如果使用本地資料
uesrname=input("
請輸入使用者名稱:
").strip()
password=input("
請輸入密碼:
").strip()
if uesrname==name : #
如果使用者存在
if password==word:#
如果密碼正確
print("
使用本地資料")
print("
歡迎進入!")
return func(*args,**kwargs) #
進入home介面
else
:
print("
密碼錯誤")
else
:
print("
使用者不存在")
elif auth_type=="
cloude
": #
如果使用雲端資料
print("
使用雲端資料")
print("歡迎"
) func()
#進入bbs介面
return
deco
return
auth_out
defindex():
print("
welcome to index page")
@auth(auth_type="
local
") #
登入home介面使用本地使用者資料,在auth()內傳參
defhome():
print("
welcome to home page")
return
"form home
"@auth(auth_type="
cloude
") #
登入bbs介面使用雲端使用者資料
defbbs():
print("
welcome to bbs page")
index()
(home())
bbs()
執行結果:
初學該怎樣理解python裝飾器
記得以前學到這裡,看了很多關於python裝飾器的文章,對於裝飾器還是一知半解,後來在一些例項中,通過最樸實的方法總算是摸清楚了什麼是裝飾器?以下是個人對裝飾器的筆記。在學習裝飾器之前,我們必須搞清楚一點,裝飾器究竟是什麼?用文字說明,裝飾器實際上就是為了給某個函式,或者稱某個程式新增乙個功能。並且...
python裝飾器 Python 裝飾器
簡言之,python裝飾器就是用於拓展原來函式功能的一種函式,這個函式的特殊之處在於它的返回值也是乙個函式,使用python裝飾器的好處就是在不用更改原函式的 前提下給函式增加新的功能。一般而言,我們要想拓展原來函式 最直接的辦法就是侵入 裡面修改,例如 這是我們最原始的的乙個函式,然後我們試圖記錄...
python裝飾器 裝飾器
由於函式也是乙個物件,而且函式物件可以被賦值給變數,所以,通過變數也能呼叫該函式。def now print 2015 3 25 f now f 2015 3 25 函式物件有乙個 name 屬性,可以拿到函式的名字 now.name now f.name now 現在,假設我們要增強now 函式的...