首先來看一下,簡單的閉包函式:
def func(x):
def func1():
return x
return func1
>>g = func(3)
>>g()
>>3
1.內部函式可以對外部函式的變數進行操作
2.外部函式返回內部函式物件
滿足以上兩點,即是閉包
在上例中,外部函式變數x,被傳入到內部函式func1中並返回,外部函式func返回內部函式的函式物件func1
函式物件加上()才為呼叫,否則只是函式物件,python萬物皆物件
接下來,來看一下,內部函式帶有引數的閉包
def func2(x):
def func3(y):
return x+y
return func3
>>g = func2(2)
>>g(3)
>>5
思考:當g = func2(2)執行完時,func2已經結束了,那麼為什麼x = 2實際上在g(2)還起作用呢?
因為當x = 2傳入func2時,內部函式保留了這個實參
可以對**做微小修改來表現:
def func2(x): #step1
#step2:
def func3(y): #step6
print(x)
return x+y#step7
return func3 #step3
>>g = func2(2) #step4
>>g(3) #step5
>>2
>>5
結合「函式物件可以作為函式引數」的特性,因此,這裡的完全可以被賦值為乙個函式物件,這是func2就成為了傳入函式的裝飾器
#乙個輸出函式__name__屬性的裝飾器
def printname(func):
def swarps(*args,**kwargs): #被修飾函式的引數將會成為內部函式的引數
print(func.__name__) #裝飾器的意義在於此
return func(*args,**kwargs) #執行原被修飾的函式,不然原函式的結果不會返回
return swarps #返回函式物件
@printname
def square(x):
return x**2
square(2)
>>square
4#將裝飾器函式與閉包函式做比較
def printname(func): def func(x):
def swarps(*args,**kwargs): def func1(y):
print(func.__name__) <<#對外部引數操作》 print(x+2)
return func(*args,**kwargs) <<#對內外部函式一起做操作》 return x+y
return swarps <<#返回內部函式物件》 return func1
@printname
def square(x): g = func(3) >> g(2) == func(3)(2)
return x**2
#裝飾器printname的執行過程
step1:將函式物件square傳入printname的形參func
step2:在printname內部定義乙個函式swarps並返回swarps,即printname(square) >>swarps
step3:x作為返回的函式物件swarps的引數,相當於執行swarps(x)
step4:執行swarp(x),並返回原函式的執行結果(return func(*args,*kwargs)一句,如果沒有這一句,原函式的執行結果將被覆蓋)
func(x)(y) >>printname(square)(x) 其實就是這樣這樣一種對應關係啦
函式名作為外部引數,函式引數作為內部引數的乙個閉包而已,懂了嗎?
帶引數的裝飾器,實際上就是對裝飾器函式進行封裝,舉例來說,同樣是剛才的printname裝飾器
#乙個簡單的帶引數裝飾器
#對printname裝飾器新增引數,要求當password = 5的時候才執行裝飾器
def addargument(password):
def printname(func):
def swarps(*args,**kwargs):
if password == '5':
print(func.__name__)
return func(*args,**kwargs)
return swarps
return printname
@addargument(5)
def square(x):
return x**2
關於類裝飾器,等學完了類和物件再來寫吧 Python 裝飾器 ,閉包
1 裝飾器 不改變被裝飾的函式情況下附加一些功能 本質是函式,用於裝飾其他函式,附加一些本身所沒有的功能 實質 是乙個函式 引數 是你要裝飾的函式名 並非函式呼叫 返回 是裝飾完的函式名 也非函式呼叫 作用 為已經存在的物件新增額外的功能 特點 不需要對物件做任何的 上的變動 例1 計算執行時長 i...
python裝飾器和閉包
下面幾個部落格有裝飾器的講解,也包含了裝飾器幾種情況的例子,比如說被裝飾的函式帶引數,裝飾器本身帶引數等。理解python中的裝飾器 python裝飾器學習 例子 其實裝飾器跟設計模式中的裝飾器模式基本一樣,就是在已有的函式上新增新的功能,這也是自己對裝飾器的一點簡陋的理解了。下面是自己寫的簡單例子...
python閉包和裝飾器
要理解裝飾器,就要明白閉包 要明白閉包,首先就要從高階函式和作用域說起 說道作用域,一般會談到legb規則。所謂的legb l locals,當前命名空間 區域性作用域 e enclosing,外部函式的命名空間 外部作用域 g global,全域性的命名空間 b bulit in,內建的命名空間平...