我從thecodeship上的一個很棒的教程中學到了一些關於裝飾器的知識,但是通過一個示例發現自己頗爲困惑。Python裝飾器示例
首先給出一個簡單的例子,然後給出一個裝飾器的解釋。
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
my_get_text = p_decorate(get_text)
print my_get_text("John")
現在這對我有意義。裝飾器只是一個函數的包裝器。在這個傢伙的解釋中,他說裝飾器是一個函數,它將另一個函數作爲參數,生成一個新函數,並返回生成的函數以在任何地方使用。
現在相當於上面的代碼是:
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
@p_decorate
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
print get_text("John")
我相信我明白如果沒有參數,一個裝飾初始化的方式。糾正我,如果我錯了。
- 默認情況下,經過裝飾的功能
get_text
因爲p_decorate
返回一個函數func_wrapper
,我們最終與真實的陳述get_text = func_wrapper
。
對我來說重要的是第一個代碼塊的等價物,因爲我看到並理解裝飾器的行爲。
什麼很讓我困惑的是下面的代碼:
def tags(tag_name):
def tags_decorator(func):
def func_wrapper(name):
return "<{0}>{1}</{0}>".format(tag_name, func(name))
return func_wrapper
return tags_decorator
@tags("p")
def get_text(name):
return "Hello "+name
print get_text("John")
再次,糾正我,如果我錯了,但是這是我的理解。
- 裝飾器接受標記字符串「p」而不是 默認函數名稱。然後函數
tags_decorator
假定將要傳遞的參數是裝飾的函數 ,get_text
。
對於我來說,在「非裝飾器」形式中看到等效的代碼塊可能會有所幫助,但我似乎無法將我的頭圍繞在看起來像什麼樣的東西上。我也不理解爲什麼tags_decorator
和func_wrapper
都返回。如果裝飾者只需要返回1個函數來包裝get_text
,那麼返回兩個不同函數的目的是什麼。
作爲一個方面說明,它真的歸結爲以下幾點。
- 該塊可以簡化爲少於一組3個功能嗎?
- 裝飾器可以接受多於一個參數來簡化代碼嗎?
謝謝。我在回覆後做了一個簡短的編輯。爲什麼這些函數返回2個函數而不是1? – Max
@Max:看我最近的編輯。一個是裝飾器(由裝飾工廠生產),另一個是用包裝代替原裝函數,裝飾器的結果。 –
我現在明白了,2個函數調用的目的。我可以用裝飾工廠製作一個特定的裝飾器來進一步指定我的最終包裝。 – Max