3

いくつかの変数を作成するコードがあるとします。

# Some code

# Beginning of the block to memoize
a = foo()
b = bar()
...
c =
# End of the block to memoize

# ... some more code

ブロック内で作成/変更されたすべての変数について明示したり、手動でピクルしたりすることなく、上記のブロック全体をメモしたいと思います。Pythonでこれを行うにはどうすればよいですか?

理想的には、それを何か (if/elseまたはwithステートメント) でラップし、必要に応じて強制的に更新するフラグを設定できるようにしたいと考えています。

概念的に言えば、次のようになります。

# Some code

# Flag that I can set from outside to save or force a reset of the chache 
refresh_cache = True

if refresh_cache == False
   load_cache_of_block()
else:      
   # Beginning of the block to memoize
   a = foo()
   b = bar()
   ...
   c = stuff()
   # End of the block to memoize

   save_cache_of_block()

# ... some more code

コードで定義または変更された各変数を明示的にピクルする必要なく、これを行う方法はありますか? (つまり、最初の実行の最後に保存し、後で値を再利用するだけです)

4

2 に答える 2

1

これには多くの方法がありますが、あなたが説明しているものに最も近い方法はmodule scope、メモ化された、importまたはreload必要に応じてpythonを使用することだと思います。このようなもの:

# a.py
import b

print b.a, b.b
b.func(5)
b.b = 'world'
print b.a, b.b

if b.needs_refresh():
    reload(b)

print b.a, b.b

「変数スコープ」がモジュールである場合b

# b.py
a = 0
b = 'hello'

def func(i):
    global a
    a += i

def needs_refresh():
    return a >= 5

これを実行すると、期待どおりの結果が得られます。

 0 hello
 5 world
 0 hello

編集:スコープ全体をコピーして保存できるようにするには、クラススコープを使用するだけです:

 memo_stack = list()

 class MemoScope(object):
     def __init__(self):
         self.a = 0
         self.b = 'hello'

 memo = MemoScope()
 memo.a = 2
 memo.b = 3

 memo_stack.append(memo)
 memo_stack.append(MemoScope())

 for i, o in enumerate(memo_stack):
     print "memo t%i.a = %s" % (i, o.a)
     print "memo t%i.b = %s" % (i, o.b)
     if o.a == 2:
         memo_stack[i] = MemoScope()
         print "refreshed"

# memo t0.a = 2
# memo t0.b = 3
# refreshed
# memo t1.a = 0
# memo t1.b = hello
于 2014-08-20T21:05:33.477 に答える
1

locals()を使用してローカル変数のリストを取得し、それらを pickle の dict に格納してから使用するのはどうですか(以下はより概念的なものです):

for k,v in vars_from_pickle:
  run_string = '%s=%s' % (k,v)
  exec(run_string)

ローカル スタックを復元します。スタックの順序を維持するために、辞書の代わりにリストを使用する方がよいかもしれません。

于 2014-08-20T21:05:58.480 に答える