関数のラッピングに渡される変数を実際に使用する関数パラメーターを持つデコレーターを作成する方法を探しています。
たとえば、私が持っているとしましょう
@cache_decorator("my_key_{}".format(foo))
def my_function(foo, bar):
pass
@cache_decorator("another_key_{}_{}".format(foo, bar)
def another_function(user, foo, bar):
pass
目標は、キャッシング ラッパーを作成することです。デコレータはキャッシュ キーを必要としますが、キーには関数に渡される変数が含まれ、ラップする関数ごとに異なります。
理想的には、これによりデコレータは特定のキーのキャッシュされた値をチェックし、見つからない場合は関数を実行して値を取得し、キャッシュします。そうすれば、値がキャッシュにある場合、値を作成するコード (つまり my_function) は実行されません。見つからない場合は my_function を実行し、結果をキャッシュに保存して返します。
別の代替手段は、ブロックに似たものになります。
def my_function(foo, bar):
cache_value("my_key_{}".format(foo),{block of code to generate value that is only called if necessary})
Objective-C または js では、これはブロックになるため、値の生成をローカルで定義して変更可能にしておくことができますが、必要な場合にのみ実行されます。私はPythonに慣れていないので、クロージャーのバージョンでこれを行う方法を完全に把握できません。
ありがとう!
更新
以下のソリューションはデコレータに対して機能しましたが、適切に無効化できるようにするために各キャッシュ エントリに追加のメタデータをアタッチする必要があるため、最終的にブロックのようなルートに行きました。このメタデータを (キャッシュ関数内ではなく) 値の生成で定義すると、保守が容易になります。これは次のようになります。
def my_function(foo, bar):
def value_func():
return code_to_generate_value_using_foo_bar
return get_set_cache(key, value_func, ...)
def get_set_cache(key, value_function, ...):
value = cache.get(key)
if value is None:
value = value_function()
cache.set(key, value)
return value