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