標籤:python
http://www.cnblogs.com/wupeiqi/articles/4938499.html
python解譯器執行順序:從上到下
def foo(): -->將foo函數讀入記憶體,但不執行函數體內容
print ‘abc‘ -->略過這行
foo -->表示foo函數,foo指向函數的記憶體位址
foo() -->表示執行foo函數,反過頭取執行函數體內容print ‘abc‘
foo = lambda a : a + 1 -->foo指向另外一個函數的記憶體位址,這個函數實現的功能是a+1
foo() -->執行a+1這個函數的函數體
函數調用函數:
def f1(arg):
arg()
def func():
print "func"
f1(func)
python解譯器從上往下執行
第一步:執行def f1(arg): 將函數寫入記憶體,但是不執行函數體的內容arg()
第二步:執行def func():將函數寫入記憶體,但是不執行函數體的內容print ‘func‘
第三步:執行f1(func)調用函數f1
第四步:執行def f1(arg): ,這時arg = func,arg指向函數的記憶體位址
第五步:執行arg(),arg() = func(),也就是執行func()函數
第六步:執行def func():
第七步:執行print ‘12‘
業務情境:
基礎平台營運編寫各種基礎函數,提供各種API給產線,來查詢資料庫,各個機器的使用方式等功能
之前調用API沒有做認證,現在想在500個函數中加入auth()函數做認證,基本的做法:
def auth():
xxxxxx
def f1():
auth() -->在函數體中增加auth()函數做認證
print "f1"
def f2():
auth() -->在函數體中增加auth()函數做認證
print "f2"
但是由於開放封閉原則:
函數體不能被修改,只能修改設定檔或者main()函數來修改函數的執行順序,或者增加新的函數來改變實現的功能
例如原來定義的函數執行順序為1->2->3->4,現在修改為1->2->2.5->4->3,增加了一個2.5功能,並且調換了3和4的順序
因此需要這樣寫:
650) this.width=650;" width="31" height="52" src="/e/u261/themes/default/images/spacer.gif" style="background:url("/e/u261/themes/default/images/word.gif") no-repeat center;border:1px solid #ddd;" alt="spacer.gif" />def auth(func):
def inner():
print ‘驗證功能‘
func()
return inner
def f1(): -->原函數
print ‘f1‘
retval = auth(f1)
retval()
第一步:執行def auth(func): ,將auth()函數載入到記憶體,但不執行函數體內容
第二步:執行def f1(): ,將f1()函數載入到記憶體,但不執行函數體內容
第三步:執行retval = auth(f1),調用auth()函數,同時傳參f1
第四步:執行def auth(func): ,這時func == f1
第五步:執行def inner():,將auth()函數載入到記憶體,但是不執行inner()函數的函數體
第六步:執行return inner,這時retval == inner,retval也就等於整個inner()函數體
第七步:執行retval(),retval()==inner(),也就是執行inner()函數體,inner()函數體中有func(),而func()==f1,就執行了原來的函數f1
如果將retval = auth(f1),改寫為f1= auth(f1) (第一個f1是新f1,第二個f1是老的f1函數)那麼業務線的人就可以不用修改代碼了
python提供了簡單的寫法,這種寫法就是裝飾器:
def auth(func):
def inner():
print ‘認證功能‘
func()
print ‘列印日誌‘
return inner
650) this.width=650;" width="18" height="28" src="/e/u261/themes/default/images/spacer.gif" style="background:url("/e/u261/themes/default/images/word.gif") no-repeat center;border:1px solid #ddd;" alt="spacer.gif" />650) this.width=650;" width="33" height="174" src="/e/u261/themes/default/images/spacer.gif" style="background:url("/e/u261/themes/default/images/word.gif") no-repeat center;border:1px solid #ddd;" alt="spacer.gif" />def auth_arg1(func):
def inner(arg):
print ‘認證功能‘
func(arg)
print ‘列印日誌‘
return inner
@auth ==》會執行f1 = auth(f1),也就是inner()函數的傳回值複製給f1
def f1():
print ‘f1‘
@auth_arg1 ==》會執行f1 = auth(f1),也就是inner()函數的傳回值複製給f1
def f2(arg):
print ‘f2,arg‘
裝飾器的實質就是在不修改f1函數體的情況下,執行f1函數之前,執行一個auth函數
有了裝飾器,基礎平台給500個函數增加認證功能,在不破壞開放封閉原則的情況下,只需要寫一個auth函數和500個@auth,auth函數的inner子函數中實現認證功能,業務線不需要做任何修改,實現的功能就是f1函數執行之前進行身分識別驗證,f1功能執行之後列印日誌
當函數f2有一個參數的時候,需要另外寫一個有一個參數的裝飾器auth_arg1,在f2之前寫上@auth_arg1即可
第5天該看06了
python筆記day5