首先我知道裝飾者是什麼。我想了解一些小方面。python裝飾器是如何定義的?
TL; DR
is decorator func1 = func2(func1) # True
is decorator func3 = func2(func1) # ???
讓我們來看看Wiki描述兩個等價的方法來裝飾功能:
@viking_chorus
def menu_item():
print("spam")
def menu_item():
print("spam")
menu_item = viking_chorus(menu_item)
現在,讓我們看看在這個website描述,特別是在部分回到裝飾者。定義了兩個功能:
def make_pretty(func):
def inner():
print("I got decorated")
func()
return inner
def ordinary():
print("I am ordinary")
然後作者裝飾功能,並調用它:
>>> pretty = make_pretty(ordinary)
>>> pretty()
I got decorated
I am ordinary
我們可以看到,筆者不使用:
>>> ordinary = make_pretty(ordinary)
這是Wiki推薦的方式(我知道Wiki有時可能是錯誤的)。所以我決定用最後的方式來裝點從這個tutorial採取的斐波那契數函數:
def memoize(f):
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n-1) + fib(n-2)
這一呼籲:
>>> fib_element = memoize(fib)
>>> fib_element(40)
把我的機器上很長一段時間,這意味着fib()
已沒有正確裝飾。執行時間與fib(40)
相當。這些電話:
>>> fib = memoize(fib)
>>> fib_element = fib # assigned after decoration
>>> fib(40)
>>> fib_element(40)
執行得很快。所以問題是:我們可以說我們在pretty = make_pretty(ordinary)
賦值中裝飾了ordinary
函數嗎?
從技術上講,沒有一個獨特的對象叫做裝飾器;它實際上只是一個將函數作爲參數並返回(或預期返回)另一個函數的函數。 * * *特別是decorator * syntax *,它提供了一個簡潔的方式來應用裝飾器函數。 '@foo def bar():...'比'def bar():...短; ...; bar = foo(bar)'。 – chepner