1

単純な中間コンパイル関数を作成しようとしています。

lst = [lambda x: calculate_urls(),
       lambda x: join_urls_with_ids(x, args[0]),
       lambda x: bucket_urls(x)]
intermediate.execute(lst)

intermediate.executeリスト内の各アイテムを実行します。最初の関数の出力は2番目の関数の入力であり、以下同様です。ラムダは、各関数が1つの引数のみを取るようにするために使用されます。(最初の入力値はNoneであるため、ここでは事実上無視されます。)

各中間ステップで、出力がピクルス化されて保存されます(現在は/tmp)。関数の中間出力がすでに存在する場合、関数の実行はスキップされ、次のステップに進みます。

関数コードの変更を検出する方法を探しています。コードをハッシュするのが簡単な方法だと思いました。誰かが関数の実装を変更したかどうかを検出して、関数を再度実行し、キャッシュされた値を無視するようにします。

func_codeハッシュ可能なAFAIKであるについて知りました。ただし、これはその特定の関数に対してのみ機能します。つまり、ハッシュは、ラムダによって呼び出される関数ではなく、上記のコードのラムダが変更された場合にのみ変更されます。私が探しているものは理論的に可能ですか?合理的な中間点はありますか?

4

2 に答える 2

2

ラムダを保存する代わりに、関数の引数のタプルのリストを保存しfunc_code、それらの関数のハッシュを作成できます。つまり、あなたが持っているものの代わりに、次のことを行います。

lst = [
    (calculate urls, ()),
    (join_urls_with_ids, (args[0])),
    (bucket_urls, ())
]

次に、intermediate.execute次のようにします。

def execute(lst):
    result = ()
    for func, args in list:
        args = result + args
        result = func(*args)

ただし、ここで何をしようとしているのかを把握するのは少し難しいです。プログラムの呼び出しごとに関数の実装が変わる可能性があるという考えはありますか?(つまり、実行、キャッシュの保存、終了、のソースコードの変更を行ってからcalculate_urls、再度実行しますか?)その場合は、代わりに関数のソースコードをハッシュする方がよい場合があります(を使用inspect.getsource)。Pythonバイトコード(に含まれているものfunc_code)は実際には安定したターゲットではなく、Pythonのバージョン間で変更される可能性があります。

于 2012-12-04T04:37:34.657 に答える
0

機能のバックアップリストを作成してみませんか?lstで何かがそれらの1つを変更した場合、リストはそれ以上等しくなりません。

lst = [lambda x: calculate_urls(),
       lambda x: join_urls_with_ids(x, args[0]),
       lambda x: bucket_urls(x)]
backup = list(lst)

lst[0] = lambda x: foo()

if lst != backup:
    print("Something changed")
于 2012-12-04T04:36:32.707 に答える