python閉包與裝飾器理解

2021-10-10 19:45:26 字數 2528 閱讀 2009

學習python遇到乙個裝飾器的例項,簡單記錄一下個人理解。

閉包也叫做閉包函式或者閉合函式,因此閉包的本質就是一類函式。與普通函式不同的是它返回的是乙個函式閉包函式一般是兩個函式的巢狀,分別稱為外層函式和內層函式,外層函式的返回值是內層函式的引用。文字描述太抽象,用下面的例項進行說明。

例如,我們要計算某個數的n次冪,可以寫成如下**:

# 計算某個數的n冪

defset_exponent

(exponent)

:def

exponent_of

(base)

:return base ** exponent

return exponent_of # 返回值是 exponent_of 函式

square = set_exponent(2)

# 計算乙個數的平方

cube = set_exponent(3)

# 計算乙個數的立方

print

(square(5)

)# 計算 5 的平方

print

(cube(5)

)# 計算 5 的立方

上述**中外層函式set_base返回的是內層函式exponent_of的引用,可以簡單地理解為外層函式對內層函式進行了一些設定,並將設定好的函式返回。抽象為偽**如下:

def 外層函式(引數1

): def 內層函式(引數2

): 內層函式功能

return 內層函式

內層函式引用 = 外層函式(

"引數"

)內層函式引用(

)

一般函式執行結束時,會將函式內的臨時變數釋放,但在閉包函式中,外層函式的引數可能會被內層函式呼叫,因此外層函式會將臨時變數與內層函式**在一起,當外層函式呼叫結束後,內層函式依舊能夠使用臨時變數,也就是說外層函式的引數可以在記憶體中保留,以便內層函式呼叫。

理解函式裝飾器可以從名字入手,通常來說「裝飾」指的是在已有的物體上新增某些新要素,使其在功能上得到一定擴充套件。python的裝飾器可以理解為對原有函式進行功能擴充套件的一種函式。裝飾器基於閉包函式實現,它的輸入是乙個函式,返回的也是乙個函式。可以理解為將某個函式返廠重新裝修了一下再返回

(為什麼擴充套件函式新功能不直接在原函式上改呢?原因有很多,例如公司的專案執行很久了,核心**已經比較穩定,如果要新增新功能直接改原函式會導致很多風險;又例如要新增的新功能不是**核心,直接加到函式中會影響可讀性,此時用裝飾器是很不錯的選擇。)

下面是乙個裝飾器例項,我們要求一串數字的平方和,要求追蹤函式和引數的變化情況,利用裝飾器寫法如下:

def

tracel

(fn)

:def

traced

(x):

print

('calling'

, fn,

'on argument'

, x)

return fn(x)

return traced

@tracel

defsquare

(x):

return x * x

@tracel

defsum_squares_up_to

(n):

k =1 total =

0while k <= n:

total, k = total + square(k)

, k+

1return total

print

(sum_squares_up_to(5)

)

輸出為:

calling > on argument 5

calling > on argument 1

calling > on argument 2

calling > on argument 3

calling > on argument 4

calling > on argument 5

55

上述**的核心是計算平方以及計算總和,利用裝飾器追蹤引數變化,避免在關鍵語句中print引數,使得**更加清晰易讀,核心**越複雜這個優勢越明顯。

# 寫法一..

.@tracel

defsquare

(x):

return x * x

# 寫法二..

.def

square

(x):

return x * x

square = tracel(square)

@符號是python中規定的,目的在於簡化寫法二,但是寫法二更好理解,結合返廠重新裝修就能體會裝飾器的作用了。

以上是個人的一些理解,如有偏差歡迎指出,另外上述例子還涉及到裝飾器引數的問題,還沒有詳細學習,日後補充。

python閉包與裝飾器

首先閉包函式我的理解是,乙個函式內可以巢狀定義乙個函式,並將巢狀定義的函式返回 如果不返回執行完函式物件也就銷毀了 巢狀函式可以接收外部函式的引數,不同引數就可以變更巢狀函式的功能,返回不同功能的巢狀函式物件。以下是閉包函式簡單示例,如果inner函式不接收outer的引數x也就沒有意義了,一定要返...

Python閉包與裝飾器

一.閉包 如果乙個內嵌函式中引用了外部函式中的變數 非全域性變數 那麼該內嵌函式稱之為閉包 也就是將組成函式的語句和這些語句的執行環境打包在一起時,得到的物件 閉包滿足的三個條件 1.必須是內嵌函式 2.外層函式返回值是內嵌函式 3.內嵌函式引用外層函式變數 def funx x def funy ...

Python 閉包與裝飾器

在函式內部再定義乙個函式,並且內部這個函式用到了外邊函式的變數,那麼將內部函式以及用到的一些變數稱之為閉包。兩個函式巢狀,外層函式返回內層函式的引用,外層函式必須傳引數 外層函式不傳參相當於只定義內層函式,沒有什麼用。注意點 由於閉包引用了外部函式的區域性變數,則外部函式的區域性變數沒有及時釋放,消...