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/elsewith语句)包装它,并有一个标志,如果我愿意,可以强制刷新。

从概念上讲,它会像:

# 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 scopepython 作为您的记忆和import/或reload根据需要。像这样的东西:

# 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中的字典中,然后使用(下面是更概念性的):

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

恢复您的本地堆栈。也许使用列表而不是字典来保留堆栈顺序会更好。

于 2014-08-20T21:05:58.480 回答