Pythonの組み込み関数の三つの方法飾るために:プロパティ、クラスメソッドとstaticmethodを。
他の一般的な装飾は、その役割が良い行動デコレータの構築を支援することで、functools.wrapsです。標準ライブラリは、最も注目すべきは、二つの装飾lru_cacheと新しいsingledispatch(Pythonの3.4新しい)です。両方functoolsデコレータは、モジュール内で定義されています。その後、我々は彼らを議論します。
1、functools.lru_cacheはノートを行います
functools.lru_cacheはメモ(メモ化)機能を実装して非常に便利なデコレータ、です。これは、同じパラメータを渡すときにダブルカウントを避けるために、一緒に時間のかかる関数の結果を保存した最適化手法です。キャッシュは、キャッシュエントリのない時間が破棄されます、無制限の成長でなくなることを示す略語、「最低使用」LRU三の文字。
#写一个装饰器用来计算时间 インポート時間 インポートfunctools デフ(FUNC)クロック: functools.wraps @(funcは) デフ(* argsを、**クロックさkwargsから): T0 = time.time()は 結果(= funcを*引数を、 ** kwargsから) 経過 = time.time() - T0の 名前 = FUNC。__name__ arg_lst = [] もし引数: arg_lst.append(' ' .join(のrepr(引数)のための引数で引数)) 場合:kwargsから ペア [= ' %S =%R '%(K、W)のために W K、でソート(kwargs.items())] arg_lst.append(' ' .join(ペア)) arg_str = ' 、' .join(arg_lst) プリント(' [%の0.8fs]%S(%S) - >%のR '%(経過、名前、arg_str、結果)) 、戻り結果 リターンクロックさ
この遅い再帰関数lru_cacheために使用されるn番目のフィボナッチ数を生成します
@clockの デフフィボナッチ(N): もし 2 <N : リターンN 戻りフィボナッチ(N-2)+フィボナッチ(N-1)
もし__name __ == '__ MAIN__':
プリント(フィボナッチ(6))
結果:
【0.00000095s]フィボナッチ(0) - > 0 [0.00000095s]フィボナッチ( 1) - > 1 [0.00007892s]フィボナッチ( 2) - > 1 [0.00000095s]フィボナッチ( 1) - > 1 [0.00000095s]フィボナッチ( 0) - > 0 [0.00000095s]フィボナッチ( 1) - > 1 [0.00003815s]フィボナッチ( 2) - > 1 [0.00007391s]フィボナッチ( 3) - > 2 [0.00018883s]フィボナッチ( 4) - > 3 [ 0.00000000s]フィボナッチ( 1) - > 1 [0.00000095s]フィボナッチ(0) - > 0 [0.00000119s]フィボナッチ( 1) - > 1 [0.00004911s]フィボナッチ( 2) - > 1 [0.00009704s]フィボナッチ( 3 ) - > 2 【0.00000000s]フィボナッチ(0) - > 0 [0.00000000s]フィボナッチ( 1) - > 1 [0.00002694s]フィボナッチ( 2) - > 1 [0.00000095s]フィボナッチ( 1) - > 1 [0.00000095s]フィボナッチ( 0) - > 0 [0.00000095s]フィボナッチ( 1) - > 1 [0.00005102s]フィボナッチ( 2) - > 1 [0.00008917s]フィボナッチ( 3) - > 2 [0.00015593s]フィボナッチ( 4) - > 3 [ 0.00029993s]フィボナッチ( 5) - > 5 [0.00052810s]フィボナッチ( 6) - > 8 8
明白な場所は、時間を無駄にする:フィボナッチは、(1)2行のコードの増加は、lru_cacheを使用する場合は5回......しかし、パフォーマンスが大幅に改善されます(2)コールフィボナッチ、8回と呼ばれます
@ functools.lru_cache() @clockの デフフィボナッチ(N): もし N <2 : リターンn個の 戻りフィボナッチ(N-2)+フィボナッチ(N-1 ) であれば __name__ == ' __main__ ' : 印刷(フィボナッチ(6))
結果:
【0.00000119s]フィボナッチ(0) - > 0 [0.00000119s]フィボナッチ( 1) - > 1 [0.00010800s]フィボナッチ( 2) - > 1 [0.00000787s]フィボナッチ( 3) - > 2 [0.00016093s]フィボナッチ( 4) - > 3 [0.00001216s]フィボナッチ( 5) - > 5 [0.00025296s]フィボナッチ( 6) - > 8 8
したがって、実行の半分の時間は、nおよび各関数の値は一度だけ呼び出されます。
特に注意、lru_cacheは、構成するために2つのオプションのパラメータを使用することができます。そのシグネチャは次のとおりです。functools.lru_cache(MAXSIZE = 128、入力された= False)が
MAXSIZEパラメータが保存されているどのように多くの呼び出しの結果を指定します。キャッシュがいっぱいになった後、結果は部屋を作るために古いものを捨てることであろう。最高のパフォーマンスを得るために、MAXSIZEは2の累乗に設定する必要があります。型付けされたパラメータがTRUEに設定すると、別々に格納されたパラメータの異なる種類によって得られた結果は、すなわち、一般的に別の浮動小数点と整数パラメータ(例えば、1.0及び1)領域に相当すると見なさ。ところで、lru_cacheので、結果を格納するために辞書を使用しますが、パラメータとキーワードパラメータを配置する際に鍵が着信コールに基づいて作成され、それがlru_cache装飾的な機能であり、そのすべてのパラメータがハッシュされなければなりません。