Python関数をメモする方法は次のとおりです。
def memo_square(a, cache={}): if a not in cache: cache[a] = a*a return cache[a]
レセプションはあまり知られていないので、カットの下で、それがどのように機能し、何のためであるかを分析します。
最初に、それがどのようにそしてなぜ働くか。
memo_square
(他の関数と同様に)関数クラスのオブジェクトであり、属性の中でも、オブジェクトの作成時に
memo_square.__defaults__
タプルが入力されます。 まず、関数ヘッダーに示されているように、空の辞書が含まれています。
>>> memo_square.__defaults__ ({},)
__defaults__
は通常のタプルであり、その要素を変更することはできません。 確かに、デフォルト値のセット全体を一度に置き換えることができますが、異なるタプルでのみ:
>>> def test(a=1, b=2): ... print(a, b) ... >>> test.__defaults__ (1, 2) >>> test() 1 2 >>> test.__defaults__ = (', ', '') >>> test() , >>> test.__defaults__[1] = '' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> test.__defaults__ = {0: ', ', 1: ''} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __defaults__ must be set to a tuple object
Soryan、この記事はPicabaには届きません。 さて、大丈夫、これは重要ではありません。 重要なことは、非常にトリッキーなコードを除いて、
func.__defaults__
がプログラムのすべての要素で一度作成されることです。 タプルとその要素は、関数呼び出しごとに再作成されるのではなく、関数が存在する限り使用されます。 しかし、変更するには、要素自体が可変である場合、誰もそれらを禁止しません。 このような要素を使用できないこと
は、Pythonで自分自身を撃つ最も一般的な方法の1つです 。 しかし、実際に関数呼び出し間で値を保存することは非常に便利です。 数回呼び出した後、
memo_square.__defaults__
は次のようになります。
>>> memo_square(2) 4 >>> memo_square.__defaults__ ({2: 4},) >>> memo_square(5) 25 >>> memo_square.__defaults__ ({2: 4, 5: 25},) >>> memo_square(2) 4 >>> memo_square.__defaults__ ({2: 4, 5: 25},)
同じ値に対して関数がすでに呼び出されている場合、値が計算され、それに応じてキャッシュは補充されません。 正方形の場合、利点は小さいです(厳密に言えば、正方形の場合、辞書での検索は2つの数字を乗算するよりも高価であるため、利益はマイナスです)が、メモ化/キャッシングは実際の高価な機能に役立ちます。 もちろん、Pythonで複数の方法で提供できます。 代替手段は次のとおりです。
このメモ化の方法が失う主なことは、あまり慣用的ではないということです。 個人的に、私がこの決定に初めて出会ったとき、私はここで何が起こっているのか、そしてその理由について数分間考えました。 一方、これらの数分で、Python関数とその引数がどのように機能するかを少し理解し始めました。 したがって、デフォルトの引数を使用しない場合(メモ化または
名前解決の高速化など )でも、この手法を知っていると、栄養士にとって役立ちます。