python內部函數、閉包共同之處在於都是以函數做爲參數傳遞到函數,不一樣之處在於返回與調用有所區別。python
python內部函數示例:閉包
def test(*args): def add(*args): # 顯示的調用外部函數的參數 return args return add(*args) # 返回內部函數的直接調用 運行結果以下: test(1,2,3) (1,2,3)
內部函數直接引用外部函數參數,外部函數test顯示的返回內部函數add的調用。
當須要在函數內部屢次執行復雜任務時,內部函數很是有用,從而避免了循環和代碼的堆疊重複。函數
內部函數能夠看做是一個閉包。閉包是一個能夠由另外一個函數動態生成的函數,而且能夠改變和存儲函數外建立的變量的值。blog
python閉包示例:cmd
def test(a): def add(): # 沒用引用外部函數的參數 return "it's a callable %s" % a # 直接在內部函數使用外部函數的參數 return add # 返回內部函數自己,不返回內部函數調用 運行結果以下: a1 = test(1) # 動態生成的一個能夠記錄外部變量的函數 <function __main__.add> a1() # 調用此函數 it's a callable 1 test(1)() # 自己調用過程,先動態生成一個函數再進行調用 it's a callable 1
裝飾器實質上是一個函數,它把一個函數做爲輸入而且返回另一個函數,在裝飾器中,一般使用下面這些python技巧:it
*args 和 **kwargsio
閉包function
做爲參數的函數class
python裝飾器示例:test
def test(func): # 將函數做爲參數進行傳遞 def add(*args,**kwargs): print 「it's a d」 return func(*args,**kwargs) # 內部函數進行相關操做之後,返回傳遞函數的調用 return add def func(a,b): return a+b 運行結果以下: test(func) # 將func做爲函數傳遞進test函數進行裝飾 <function __main__.add> # 裝飾後的函數,相似閉包 test(func)(1,2) # 顯示的對裝飾後的函數進行調用 it's a d # 中間被裝飾的過程被print出來 3 更簡單的方法調用裝飾器 @test # 同一個函數能夠調用多個裝飾器,執行過程當中不分前後順序 def func(a,b): return a+b 不管傳入test()的函數func是什麼,裝飾器都會返回一個新的函數,其中包含test增長的額外語句。
實際上,裝飾器並不須要執行函數func中的代碼,只是在結束前函數add調用函數func以獲得的func返回的結果和附加代碼的結果
裝飾器自己須要傳遞參數的時候:
def test(cmd): # 將參數傳遞 def exc(func): # 第二步進行函數做爲參數傳遞 def add(*args,**kwargs): print "it's a %s" % cmd print "begin" return func(*args,**kwargs) return add return exc 運行結果以下: test('haha') <function __main__.exc> test('haha')(func)(1,2) # 調用裝飾器返回結果 it's a haha begin 3 更簡單的方法調用 @test('haha') # test函數進行了參數傳遞 def func(a,b): return a+b
python裝飾器注意事項:
對func進行裝飾之後,func的函數命名空間發生了變化
執行 func.__name__ add
如何指向原來的命名空間呢?python自帶了functools庫直接調用則行
import functools def test(func): @functools.wraps(func) def add(*args,**kwargs): print "it's a decorator" return func(*args,**kwargs) return add @test def func(a,b): return a+b 再次運行,查看命名空間 func.__name__ func # 返回了自己