若是看完這篇文章,你仍是弄不明白裝飾器;
你來找我,我保證不打你,我給你發100的大紅包。數據結構
mySum:計算列表的和,參數必須爲列表
myMax:統計列表的最大值,參數必須爲列表閉包
代碼實現:框架
def mySum(args): #判斷args是不是列表 if isinstance(args, list): return sum(args) return -1 def myMax(args): #判斷args是不是列表 if isinstance(args, list): return max(args) return -1 print(mySum([1,2,3])) print(mySum((1,2,3))) print(myMax(123))
結果:6, -1, -1ide
修改代碼:函數
def mySum(args): #判斷args是不是列表 if isinstance(args, (list, tuple)): return sum(args) return -1 def myMax(args): #判斷args是不是列表 if isinstance(args, (list, tuple)): return max(args) return -1 print(mySum([1,2,3])) print(mySum((1,2,3))) print(myMax(123))
結果:6,6,-1code
從上一步修改中能夠看到,判斷條件時相同的,惟一不一樣時處理方式。作用域
對上面進行分析,解決方式:get
每一個函數的核心功能不一樣,可是判斷條件相同
將相同部分拆分紅函數,使用閉包處理下:it
def decoFunc(func): #checkArgs爲內置函數,func對於checkArgs是外部變量 def checkArgs(args): #統一處理參數 if isinstance(args, (list, tuple)): return func(args) return -1 return checkArgs #自定義的sun函數 mySum = decoFunc(sum) #自定義max函數 myMax = decoFunc(max) print(mySum([1,2,3])) print(mySum((1,2,3))) print(myMax(123))
結果:6,6,-1io
decoFunc(func)中的func對於checkArgs爲外部變量
decoFunc返回值爲checkArgs函數
mySum, myMax指向checkArgs函數,可是每一個函數內部的func不一樣
mySum, myMax調用以後,檢查args,而後使用不一樣func處理ars
你們能夠吧這個過程理解下,而後咱們來看裝飾器
如何理裝飾器:
裝飾器:修改函數並返回新的函數;
裝飾器與閉包原理相似,可是隻用來處理函數;
基本語法:
@deco def func(args): pass
來看例子
def decoFunc(func): #checkArgs爲內置函數,func對於checkArgs是外部變量 def checkArgs(args): #統一處理參數 if isinstance(args, (list, tuple)): return func(args) return -1 print('checkArgs:', checkArgs) return checkArgs @decoFunc def mySum(args): return sum(args) print('mySum:', mySum)
結果:
checkArgs: <function decoFunc.<locals>.checkArgs at 0x000001C4A21580D8> mySum: <function decoFunc.<locals>.checkArgs at 0x000001C4A21580D8>
分析:
mySum變量名指向decoFunc中的返回值:checkArgs函數br/>@decoFunc就是裝飾器的語法糖
從結果中看到,咱們沒有調用mySum函數,可是裝飾器函數會默認執行
裝飾器實質:對比兩個例子,裝飾器實質:mySum = decoFunc(mySum)
新需求:在不修改checkArgs參數前提下,調用mySum,myMax前打印相應的函數名
直接上代碼:
def decoFunc(fname): print("call decoFunc") #在_decoFunc在加一層函數,返回_decoFunc def _decoFunc(func): #checkArgs爲內置函數,func對於checkArgs是外部變量 def checkArgs(args): #統一處理參數 if isinstance(args, (list, tuple)): print("call func:", fname) return func(args) return -1 print('checkArgs:', checkArgs) return checkArgs return _decoFunc @decoFunc('mySum') def mySum(args): return sum(args) print('mySum:', mySum) mySum([1,2,3,4,5])
結果:
call decoFunc checkArgs: <function decoFunc.<locals>._decoFunc.<locals>.checkArgs at 0x000001C4A1D00B88> mySum: <function decoFunc.<locals>._decoFunc.<locals>.checkArgs at 0x000001C4A1D00B88> call func: mySum
分析:
函數包含關係:decoFunc->_decoFunc->checkArgs
@decoFunc('mySum')執行過程:
1.執行decoFunc('mySum'),設置fname,返回_decoFuncbr/>2.執行@decoFunc('mySum')實質是@返回_decoFunc,
3>mysum = _decoFunc(mySum)
你們看到裝飾器,尤爲帶參數的裝飾器,感受暈暈的,
咱們要作的,就是一步一步分析,搞清楚原理;
以上就是裝飾相關內容;