1

我发现以下帖子非常有帮助: 如何腌制自己?

但是,此解决方案的局限性在于,当类重新加载时,它不会以其“运行时”状态返回。即它将重新加载所有变量等以及在它被转储的那一刻类的一般状态..但它不会从那时起继续运行。

考虑:

class someClass(object):
   def doSomething(self):
       i = 0         
       while i <= 20:
          execute
          i += 1
          if i == 10:
             self.dumpState()

   def dumpState(self):
      with open('somePickleFile','wb') as handle:
         pickle.dump(self, handle)

   @classmethod
   def loadState(cls, file_name):
      with open(file_name, 'rb') as handle:
          return pickle.load(handle)

如果上面运行,通过创建 someClass 的实例:

 sC = someClass()
 sC.doSomething()
 sC.loadState('somePickleFile')

这不会将类返回到其运行时状态,它不会继续执行 while 循环,直到 i == 20..

这可能不是正确的方法,但我正在尝试找到一种方法来捕获我的程序的运行时状态,即冻结/休眠它,然后在可能将其移动到另一台机器后重新启动它。这是由于我遇到的问题由不支持检查点的集群上的排队系统强制执行的时间限制。

4

3 回答 3

1

如果您的代码没有意识到这一点,那么仅使用 Pickle 和 Unpickle 就无法实现这种方法。

Pickle 可以保存基本的 Python 对象,以及引用这些基本类型的普通用户类。但它不能根据需要冻结运行上下文的信息。

Python 确实允许通过其框架对象访问正在运行的代码上下文的有限(但功能强大)的方式 - 您可以通过在检查模块中调用“inspect.currentframe”来获取框架对象。这将允许您查看当前正在运行的代码行、局部变量、局部变量的内容等等——但是在纯 python 内部没有办法,除非诉诸 Python 解释器的数据结构的原始内存操作来重建一个中间执行框架对象并将执行跳转到那里。

所以 - 对于这种方法,最好使用 OS 方式“冻结”整个进程及其内存数据结构(在 Linux 中可能有一种方法,它应该在没有文件/文件之类的资源的情况下工作)进程使用)。

或者,在 Python 中,如您所愿,您必须以 Pickle 能够“看到”的方式对所有状态数据进行“账簿检查”。在您的基本示例中,您应该将代码重构为:

class someClass(object):
   def setup(self):
       self.i = 0
   def doSomething(self):       
       while self.i <= 20:
          execute
          i += 1
          if i == 10:
             self.dumpState()
   ...
  @classmethod
   def loadState(cls, file_name):
      with open(file_name, 'rb') as handle:
          self = pickle.load(handle)
      if self.i <= 20: # or other check for "running context"
          return self.doSomething()

这里的根本区别是将原本本地的“i”变量记为对象变量,并将初始化代码分开。这样,继续执行所需的所有状态——对于这个小例子——都记录在对象属性上——可以适当地腌制。

于 2012-03-06T19:23:01.773 回答
0

loadState是一个classmethod返回的新实例someClass(或其他腌制到文件中的东西)。所以你应该改写:

sC = someClass()
sC.doSomething()
sC = someClass.loadState('somePickleFile')
于 2012-03-06T14:48:42.753 回答
0

我相信pickle只保留实例的属性值,而不是任何正在执行的方法的内部状态。它不会保存方法正在执行的事实,也不会保存局部变量的值,就像您的示例中的 i 一样。

于 2012-03-06T14:52:44.637 回答