Python-裝飾器詳解

閉包
在學裝飾器之前,我們先來學學閉包,因爲裝飾器需要用到閉包,那麼什麼是閉包呢?下面通過一個簡單的程序來演示,像以下的代碼我們稱之爲閉包。

def func_out(x):
	def func_in():
		print(x)
	return func_in
test = func_out(6)       # P1
test()					 #P2

簡單的來看,就是函數裏面嵌套一個函數,當程序執行到P1位置的時候,運行func_out函數,然而func_in函數沒有運行,而且以返回值的現實返回給test,也就是說test現在指向這個函數所在的空間。然後當運行到P2位置的時候,func_in函數纔開始運行。
二. 裝飾器原理
下面來讓我們來看一下這個程序

def func_out(func):
	def func_in():
		print("haha")
		func()
	return func_in
	
def test():
	print(6)

test = func_out(test)			#P1
				
test()							#P2

這也是一個閉包,只不過傳遞給閉包的參數是一個函數,當程序運行到P1的時候,func是指向test函數的區域的,然後將func_in返回給test,此時原來test函數那塊區域由現在的func指向,而現在的test指向func_in函數;當運行到P2的時候,也就是運行的是func_in函數,然後運行func函數。

ps:動手畫一下地址的指向,相信你很快就會明白其中的原理的。

從上面來看,同樣是調用test,運行的結果在原來test函數的基礎上增加了func_out這個閉包的功能,這也就是我們常說的裝飾器,在python中可以將其等價於一下寫法。

@func_out   			#P3
def test():
	print(6)
test()

就是將P1處的代碼寫成P3處的代碼,這樣我們就實現了一個簡單的裝飾器了。

帶參數函數的裝飾器

def func_out(func):
	def func_in(a,b):
		print("a=%d b=%d"%(a,b))
		func(a,b)
		
	return func_in

@func_out   			#P3
def test(a,b):			#P4
	print("a+b=%d"%(a+b))
test(11,12)

現在運行的test函數,就是func_in函數,func指向P4處的test,此處test函數包含兩個參數,所以func也要傳遞兩個參數,那麼這個參數從哪裏來呢?顯然是從func_in函數來,它的參數是由外部傳遞過來的,所以func_in需要包含兩個形參,然後給func傳遞。

.帶返回值的裝飾器

def func_out(func):
	def func_in(a,b):
		print("a=%d b=%d"%(a,b))
		res = func(a,b)    #P1
		return res
	return func_in

@func_out   			#P3
def test(a,b):			#P4
	print("a+b=%d"%(a+b))
	return a+b
res = test(11,12)      #P5
print(res)

P4處的test函數的返回值返回給P1處的res,然後func_in函數的返回值返回給P5處的res。原因前面也說過了,func其實就是P4處的test函數,而P5處的函數其實就是func_in函數

.帶有參數的裝飾器

def func_extern(arg):
	def func_out(func):
		def func_in(a,b):
			print("a=%d b=%d"%(a,b))
			res = func(a,b)    
			print("arg=%s"%arg)
			return res
		return func_in
	return func_out

@func_out("abc")  			#P3
def test(a,b):			#P4
	print("a+b=%d"%(a+b))
	return a+b
res = test(11,12)      #P5
print(res)

在這裏已經看到了三個函數嵌套了,肯定暈了吧。其實就裏面兩個函數來看,就是前面的閉包,只不過在外面嵌套的一個函數,那這個函數的功能就是來接收裝飾器傳遞過來的參數的。

在這裏裝飾器的基本功能已經說完了,這部分內容主要是理解函數的引用。

Thank for your read !!!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章