Травление себя и возвращение в рабочее состояние? - PullRequest
1 голос
/ 06 марта 2012

Я нашел следующий пост чрезвычайно полезным: Как выбрать себя?

однако ограничение этого решения состоит в том, что когда класс перезагружается, он не возвращается во время выполнения." государство.т.е. он перезагрузит все переменные и т. д. и общее состояние класса в момент, когда он был выгружен ... но он не будет продолжать работать с этой точки.

Обратите внимание:

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 до тех пор, пока я == 20 ..

Возможно, это неправильный подход, но я пытаюсь найти способ зафиксировать состояние выполнения моей программы, т.е. заморозить / перевести его в спящий режим., а затем перезапустите его после возможного перемещения на другую машину. Это связано с проблемами, связанными с ограничениями по времени, которые применяются системой очередей в кластере, который не поддерживает контрольные точки.

Ответы [ 3 ]

1 голос
/ 06 марта 2012

Такой подход не будет возможен только с 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» в качестве переменной объекта и отделении кода инициализации.,Таким образом, все состояние, необходимое для продолжения выполнения - для этого небольшого примера - записывается в атрибутах объекта - которые могут быть правильно выбраны.

0 голосов
/ 06 марта 2012

Я считаю, что pickle сохраняет только значения атрибутов экземпляра, а не внутреннее состояние выполняемых методов.Это не сохранит тот факт, что метод выполнялся, и не сохранит значения локальных переменных, как я в вашем примере.

0 голосов
/ 06 марта 2012

loadState - это classmethod, возвращающий новый экземпляр someClass (или что-то еще, добавленное в файл).Поэтому вместо этого вы должны написать:

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