編輯:我只是意識到你有一個文章鏈接,從字面上解釋了什麼是裝飾器是一步一步......但這已經是打完了所以......
有一個叫Python中關閉/函數閉包功能。
這是一段時間,因爲我試圖解釋/理解在關閉/裝飾器下發生的情況,所以這可能實際上是錯誤的。
功能func_wrapper正在每次p_decorate
被稱爲重新定義,並func_wrapper會記住封閉命名空間看起來像在定義什麼時間。
這是什麼意思:
舉個例子,假設你有一些外部變量嵌套在p_decorate
中你希望它拋出一個錯誤,因爲它不再存在(它的非本地func_wrapper)時func_wrapper
被調用並嘗試使用這個變量,但它不會因爲封閉的命名空間「記住」
在Python 3是__closure__
和蟒蛇2這是func_closure
下面。
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name)) #Cached result
print(func_wrapper.func_closure)
return func_wrapper
my_get_text1 = p_decorate(get_text)
my_get_text2 = p_decorate(get_text2)
func_closure東西:
my_get_text1 >>> (<cell at 0x*: function object at 0x*>,)
my_get_text2 >>> (<cell at 0x(different address): function object at (diff address)>,)
我們不是通過不同功能的func_wrapper
功能,但正在建設的func_wrapper
功能「記住」什麼功能,應該通過func
調用的自定義版本。
如果你在同一個函數傳遞兩次my_get_text1
和my_get_text2
你必須爲func_wrapper.func_closure
位,內存地址,一切都完全一樣的事情function object at *
,因爲它是相同的功能。 (當你用一個潛在的不同的參數實際調用它時減去。)
裝飾:
裝飾器是正如你指出一個簡單的調用,需要一個函數作爲參數,並返回一個替換功能。在你的代碼中,這將分別是p_decorator
和func_wrapper
。
如果你想在面向對象的方式思考這個......你能想到的p_decorate
作爲功能func_wrapper
構造與FUNC像個私有成員變量/屬性,因爲你已經或多或少基本建成與功能一個硬編碼的參數func
。
爲什麼它返回它做什麼:
希望上面是正確的+有道理......然後,返回你看,因爲你已經通過了get_text
功能被「記住」的價值,因爲func_wrapper
返回...你用的John
參數調用func_wrapper(arg)
現在這裏面... func_wrapper
返回如下:
"<p>{0}</p>".format(func(name))"
隨着func
爲get_text
。所以,get_text
被稱爲返回...
"lorem ipsum, {0} dolor sit amet".format(name)
然後這是開口之間格式化和關閉p
標記,然後返回。
你可以有多層嵌套的函數,就像python中的任何東西一樣,它都是烏龜。
爲什麼即使打擾使用裝飾?
在這個例子中,我認爲你是對的,我只是使用第二個函數,因爲這是一個非常沒用的例子。
但是,考慮更具體的東西。我會用一個普通的django裝飾器作爲我的頭頂的例子。即使你不熟悉Django,這應該仍然有意義。
在django中,您有可以呈現網頁的函數/視圖,有時您可能想要用戶登錄才能查看頁面。現在
,你要想這對,如果你有寫自定義邏輯每一個功能什麼。
這將是可怕的。相反,有一個名爲@login_required
的漂亮的裝飾器,您只需將它放在您希望使用此功能的函數的頂部,並且您只需保存大量時間/重複的代碼即可,因爲此裝飾器將此自定義邏輯封裝在您已應用它的函數。
裝飾器主要用於想要擴展/自定義功能而無需重新編碼所有內容。
甚至比功能更進一步...如果您想將此應用於class
的方法,該怎麼辦?也許他們都滿足某些標準?它會變得乏味,並且可能讓人煩惱,因爲每一種方法都必須這樣做。您可以編寫一個裝飾器來包裝類,並將其應用於每個函數,並自動爲您自動創建一個函數,而不是使用@decorator_name
包裝每一種方法。
你在混淆函數和函數返回。裝飾器可以根據給定的參數(另一個函數)返回不同的函數。它不會調用它返回的函數,但通常是它返回的函數,*在調用*時調用最初提供給裝飾器的函數。 – zondo
顯然你沒有閱讀那篇文章的其餘部分......它在艱苦的細節中解釋了究竟發生了什麼,目標是什麼,以及如何使用python提供的工具來實現該目標...... –
@JeffMercado:也許這就是爲什麼他提到這篇文章有一個「更明智的定義」......他沒有告訴我們哪篇文章對他沒有意義。 – zondo