python 從閉包到裝飾器

2021-08-22 13:18:47 字數 2651 閱讀 8556

首先來看一下,簡單的閉包函式:

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,內建的命名空間平...