【问题标题】:Pickling Self and Return to Run-state?酸洗自我并返回运行状态?
【发布时间】:2012-03-06 14:18:13
【问题描述】:

我发现以下帖子非常有帮助: How to pickle yourself?

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

考虑:

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..

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

【问题讨论】:

    标签: python pickle checkpoint


    【解决方案1】:

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

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

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

    所以 - 对于这种方法,最好使用操作系统“冻结”整个进程及其内存数据结构。这样做的方法(在 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”变量记为对象变量,并将初始化代码分开。通过这种方式,继续执行所需的所有状态(对于这个小示例)都记录在对象属性上 - 可以正确腌制。

    【讨论】:

    • 谢谢..我试过了,它基本上可以满足我的需要...谢谢。
    • 刚刚在 Python 列表中收到一封包含相关对象的电子邮件 - 检查 bugs.python.org/issue14288 - python 3.3 很可能可以添加对酸洗迭代器的支持,并使酸洗运行状态变得更容易。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2014-09-15
        • 1970-01-01
        • 2012-07-24
        • 2014-08-13
        • 2021-10-25
        • 1970-01-01
        • 1970-01-01
        • 2019-05-01
        • 1970-01-01
        相关资源
        最近更新 更多