初學 Python(十五)——裝飾器

Coffee_zq發表於2016-12-11

初學 Python(十五)——裝飾器

 

  初學 Python,主要整理一些學習到的知識點,這次是生成器。

#-*- coding:utf-8 -*-  
import functools  
def current():  
    print 'nihao'  
current()  
g = current  
g()  
#函式有預設欄位__name__(2個下劃線)  
print current.__name__  
print g.__name__  
  
  
''''' 
裝飾器的定義 
在不改變某個函式的內部程式碼的情況下 
在執行函式的前後加上一些邏輯 
稱作裝飾器 
'''  
#舉例,在current函式執行前列印一行日誌  
  
def log(func):  
    def wrapper(*args,**kw):  
        print 'call %s()'%func.__name__  
        return func(*args,**kw)  
    return wrapper  
 
@log  
def current2():  
    print 'nihao'  
  
current2()  
  
''''' 
看例解疑: 
當給current2函式加上@log後 
會發現current2執行前先列印了call current2() 
這是因為裝飾器的呼叫相當於把後面跟的函式放進了 
裝飾器裡面去了.上面執行current2步驟: 
1.執行current2(),返回wrapper() 
2.執行wrapper(),列印call current2(),得到current2() 
3.執行current2(),列印'nihao' 
'''  
  
#上面的@log定義等同於下面的形式  
#current2 = log(current2)  
current2()  
print 'current2函式名:'  
print current2.__name__  
  
#上面的裝飾器本身不帶引數,為2層巢狀.  
#如何要帶引數,那就要3層巢狀,先獲得引數  
def logt(text):  
    def log(func):  
        @functools.wraps(func)  
        def wrapper(*args,**kw):  
            print '%s %s():'% (text,func.__name__)  
            return func(*args,**kw)  
        return wrapper  
    return log  
@logt('execute')  
def current3():  
    print 'nihaoa'  
print '呼叫裝飾器logt:'  
current3()  
  
''''' 
上面的寫法很容看出來執行的步驟 
1.執行current3(),得到log() 
然後就跟之前的順序一樣 
'''  
#@logt定義等同下面的形式  
#current3 = logt('execute')(current3)  
#但是你會發現它列印的資訊中有wrapper函式  
#而且函式名稱也變為了wrapper  
print '執行經過裝飾器改裝後的current3:'  
current3()  
  
print 'current3函式名:'  
print current3.__name__  
#這是什麼原因,我也不知道#正在理解中  
  
#解決方法是加上這麼一句@functools.wraps(func)就解決啦  

 

相關文章