天天看點

函數之閉包與裝飾器(自我感覺這是函數中最難了解的東西)

函數之閉包與裝飾器(自我感覺這是函數中最難了解的東西)

Hello!大家好!我又雙叒叕來了,咱們今天繼續一起來學習python吧!

咱們今天繼續昨天的學習,昨天學到了函數的内置函數,但是要到達第五層還需要把函數的閉包和裝飾器給KO掉。

廢話不多說,咱馬上開始吧。

函數的閉包

函數的閉包就是利用了函數的局部性(這是我個人定義的詞),利用函數中的内部的代碼,不可以被函數外部調用。進而保證了在大項目中,避免出現由不同開發人員共同開發項目而導緻的使用的變量名可能重複的全局變量污染問題。

函數的閉包是函數的一種特殊的使用方式,主要格式為一個函數中定義另一個函數。

"""函數的基礎閉包格式"""
def func1():
	"""外部函數func1"""
	def func2():
		"""内部函數func2"""
		print("這是func2函數")
	print("這是func1函數")
           

看向上面的代碼,這樣我們就完成了一個簡單的閉包。每個func1函數可以類比一個開發者,每個func2函數可以類比開發者開發的功能代碼。每個開發者都把代碼封裝在函數中,利用函數的局部性,就可以避免全局污染問題。

函數之裝飾器

(他來了,他來了,他帶着微笑走來了^ _ ^)

在我們日常進行項目開發中,我們或多或少都會接觸到别人開發的項目,然後有可能在這基礎上給别人的代碼增加新功能。但是我們在增加功能的時候不能直接修改别人的代碼,因為有可能會影響到别人項目中原來的功能。這就涉及到項目開發的六原則之一的開閉原則。

PS:感興趣的小夥伴可以自行了解一下開發六原則。

在這個時候,裝飾器就可以很好的裝逼 實作功能了。

裝飾器的格式

一個裝飾器需要滿足的條件:

①需要是閉包函數

②内層函數需要調用外層函數的參數

③外層函數需要傳回内層函數

"""裝飾器"""
def outer(f):
	def inner():
		f()
	return inner
# 上面的代碼就是一個裝飾器基本的架構

@outer        # 調用裝飾器,給函數func()裝上裝飾器
def func():
	print("裝飾器")

func()
           

裝飾器的結構是比較簡單的,但是裝飾器的執行順序是比較難了解的。

①首先我們來看一下沒裝裝飾器的執行結果

函數之閉包與裝飾器(自我感覺這是函數中最難了解的東西)

很簡單對吧。

②我們再來看一下裝上裝飾器的執行結果

函數之閉包與裝飾器(自我感覺這是函數中最難了解的東西)

看到結果,有沒有很驚訝,明明調用的的是func()函數,但是除了func()函數之外,裝飾器的中的代碼也執行了,就相當于在原代碼基礎上增加新功能啦,這就是裝飾器的魅力了。

單個裝飾器的執行流程:

紅色表示第一步,藍色表示第二步,其中@outer相當于func=outer(func)

函數之閉包與裝飾器(自我感覺這是函數中最難了解的東西)

兩個裝飾器的執行流程:

函數之閉包與裝飾器(自我感覺這是函數中最難了解的東西)

我覺得裝飾器最難了解的地方在于怎麼捋清楚他們之間的各個函數的傳回值,幾乎所有裝飾器都是通過傳回值來進行下一層函數的調用,需要明白的幾個點在于調用函數與函數對象的差別,和函數之間的傳參問題,把三個地方捋清楚了,就基本可以明白裝飾器的原理了!