2012-03-06 2 views
1

я нашел следующее сообщение чрезвычайно полезно: How to pickle yourself?Травление себя и возвращение в состояние Run?

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

Рассмотрим:

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 loop до i == 20 ..

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

ответ

1

Этот подход невозможен с использованием Pickle и Unpickle, если ваш код не знает об этом.

Pickle может сохранять основные объекты Python и обычные пользовательские классы, которые ссылаются на эти основные типы. Но он не может заморозить информацию о текущем контексте по своему усмотрению.

Python действительно позволяет ограниченные (но мощные) способы выполнения контекста работающего кода через его объекты кадра - вы можете получить объект фрейма с вызовом функции «inspect.currentframe» в модуле проверки. Это позволит вам увидеть текущую текущую строку кода, локальные переменные, содержимое локальных переменных и т. Д. - но нет никакого пути внутри pure-python, не прибегая к необработанной манипуляции с памятью структур данных интерпретатора Python для перестройки объект кадра среднего исполнения и выполнить переход туда.

Итак - для этого подхода было бы лучше «заморозить» весь процесс и его структуры данных памяти с использованием O.S. способ сделать это (вероятно, есть путь к этому в 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() 

Принципиальное различие здесь является ведение бухгалтерского учета в противном случае локального «я» varianble в качестве переменной объекта, и отделить код initization. Таким образом, все состояние, необходимое для продолжения выполнения - для этого небольшого примера - записывается в атрибутах объекта - которое можно правильно мариновать.

+0

Спасибо .. Я попробовал это, и он работает по большому счету для того, что мне нужно ... спасибо. – aurobhima

+0

Просто получил электронное письмо в списках Python со связанным объектом - проверьте http://bugs.python.org/issue14288 - вполне возможно, что python 3.3 может добавить поддержку итераторов травления и упростить рассортирование рабочих состояний , – jsbueno

0

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

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

спасибо за исправление. – aurobhima

0

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

Смежные вопросы