1. 程式人生 > 實用技巧 >py函式裝飾器-s

py函式裝飾器-s

函式裝飾器:

概念:通過修改其他函式的功能,有助於讓程式碼更簡短 原則:已經實現了的功能程式碼,儘量不修改,對現有的程式碼進行擴充套件修改
例1:
def f():#假設一個函式f() return "helloworld" #這是預設返回值 print(f()) #呼叫f()函式並列印。 f1=f #將函式賦值給一個變數,這裡沒有使用f(),少了括號()的原因是因為這不是呼叫函式,
      #而是將函式f放到變數f1裡面
print(f1()) #然後來列印一下變數f1的結果,可見f1()會返回函式f的返回值 #====結論:函式可以賦值給變數,通過呼叫變數,來呼叫函式



#例2: def f(): print("first,helloworld") def f1(): return "second,heloworld" def f2(): return "third,helloworld" print(f1()) print(f2()) print(f()) print(f1()) #===結論:函式可以巢狀函式,當函式被呼叫時,函式內部函式也預設呼叫並列印,
      #但是直接在函式外呼叫函式內部的函式卻不行,會報錯!!!



#例3: def f(username="qika"
,pwd="123456"): #給定預設引數username,pwd def f1(): #巢狀2個函式 return "f1,heloworld" def f2(): return "f2,helloworld" if username == "qika" and pwd =="123456": #判斷一下:當username\pwd和預設相等即返回f1,
                              #不等或其他錯誤的都返回f2
return f1
#return f1() else: return f2 #return f2() print(f()) #呼叫預設的,就會預設傳參是username="qika",pwd="123456",並返回f1(函式形式) print(f(11,1)) #傳參不為username="qika",pwd="123456",(即傳入和預期不符)那麼就會返回f2(函式形式) #注意!!!:當上面呼叫f1\f2時,會返回函式,當呼叫的函式返回值是f1(),f2(),那麼就會返回這兩個函式下的返回值 #======結論:函式巢狀函式,也可以直接返回函式,也可以返回函式內部的函式的返回值;(多層)

#例4: def f(): return "first,helloworld" def f2(arg): print("second,helloworld") print("這裡列印呼叫一下:傳遞進來當做函式引數的函式:{0}".format(arg()))
f2(f)#直接將上一個函式的函式名傳入下一個函式的內當做引數。
#看懂了嗎?簡單直白一點: def f3(): print("返回值first") def f4(func): func() f4(f3) #呼叫:將函式名直接當做函式引數傳遞使用 #=====結論:函式可以當做引數進行傳遞使用,方法:將函式名當做引數,直接傳遞進下一個函式內即可 =====================================================================
以上,裝飾器的簡單語法總結! 後面還有函式的內建裝飾器介紹:https://www.cnblogs.com/QiKa/p/13532042.html







裝飾器使用:
++++++++++++++++++++++++++++++++++++++++++++++++++++++ #=============1、使用多個裝飾器========== def f(func):#定義函式f print('enter f', func) def f1(): print('running f1') func() return f1 def a(func):#定義函式a print('enter a', func) def a1(): print('running,a1') func() return a1 @f #使用兩個裝飾器f和a: @a def main(): print('running main') if __name__ == '__main__': main() #結論:裝飾器可對一個函式使用多個: # 函式main()先被a裝飾,變成新的函式,變成另一個函式後,再次被 f 裝飾器修飾,不過執行函式是從上至下來的 #===========2、裝飾器帶引數===================== def use_logging(level): def decorator(func): def wrapper(*args, **kwargs): if level == "warn": logging.warn("%s is running" % func.__name__) elif level == "info": logging.info("%s is running" % func.__name__) return func(*args) return wrapper return decorator @use_logging(level="warn") #裝飾器帶引數 def foo(name='foo'): print("i am %s" % name) foo() # #結論: # 實際上是對原有裝飾器的一個函式封裝,並返回一個裝飾器。可以將它理解為一個含有引數的閉包函式 # 當使用裝飾器:@use_logging(level="warn")呼叫時,Py自動發現這一層的封裝,並把引數傳遞到裝飾器的環境中。 # 即:@use_logging(level="warn") 等價於 @decorator,引數會預設傳遞進入