まず最初に、私はデコレータが何であるか知っています。私はいくつかの小さな側面を理解したいと思います。 、今実際にPythonデコレータはどのように定義されていますか?
@viking_chorus
def menu_item():
print("spam")
def menu_item():
print("spam")
menu_item = viking_chorus(menu_item)
のは、このwebsiteに説明を見てみましょう:;
TL DR
is decorator func1 = func2(func1) # True
is decorator func3 = func2(func1) # ???
はの機能を飾るために2つの同等の方法を説明しWikiを見てみましょう特にセクションのデコレータに戻る。そこ定義された2つの関数です:
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)
実行が速い。だから問題は:ordinary
の機能をpretty = make_pretty(ordinary)
に飾っていると言うことができますか?
技術的には、デコレータと呼ばれる明確なオブジェクトはありません。実際には関数を引数としてとり、別の関数を返す(または返すことが期待される)関数です。何が*特別なのはデコレータ*構文*であり、これはデコレータ機能を簡潔に適用する方法を提供する。 '@foo def bar():...'は 'def bar():...よりも短いです。 bar = foo(bar) 'となります。 – chepner