2015-06-03 2 views
5

У меня действительно большой объект json, который я хочу сбросить в файл рассола. Есть ли способ отображения индикатора выполнения при использовании pickle.dump?Рассол для дампа с индикатором хода

+0

Это почти мгновенно. Зачем вам нужен индикатор выполнения? ваш размер файла превышает 10 МБ? – ZdaR

+0

Ну, размер json, который я пытаюсь сбросить, может быть произвольным. – Sidd

+0

ОК, поэтому я предлагаю вам ** опрос ** с регулярными небольшими интервалами (~ 0,0001 секунд) до тех пор, пока размер файла файла не станет постоянным, если вы знаете приблизительный размер файла .p' pickle, созданного заранее , Не могу сказать вам точные параметры, поскольку у меня нет такого большого файла 'JSON'. – ZdaR

ответ

0

Единственный способ, которым я знаю, это определить методы getstate/setstate для возврата «вспомогательных объектов», которые могут обновить графический интерфейс при получении маринованного/незакрашенного. Например, если ваш объект находится список, вы могли бы использовать что-то вроде этого:

import pickle 

class SubList: 
    on_pickling = None 

    def __init__(self, sublist): 
     print('SubList', sublist) 
     self.data = sublist 

    def __getstate__(self): 
     if SubList.on_pickling is not None: 
      print('SubList pickle state fetch: calling sub callback') 
      SubList.on_pickling() 
     return self.data 

    def __setstate__(self, obj): 
     if SubList.on_pickling is not None: 
      print('SubList pickle state restore: calling sub callback') 
      SubList.on_pickling() 
     self.data = obj 


class ListSubPickler: 
    def __init__(self, data: list): 
     self.data = data 

    def __getstate__(self): 
     print('creating SubLists for pickling long list') 
     num_chunks = 10 
     span = int(len(self.data)/num_chunks) 
     SubLists = [SubList(self.data[i:(i + span)]) for i in range(0, len(self.data), span)] 
     return SubLists 

    def __setstate__(self, subpickles): 
     self.data = [] 
     print('restoring Pickleable(list)') 
     for subpickle in subpickles: 
      self.data.extend(subpickle.data) 
     print('final', self.data) 


def refresh(): 
    # do something: refresh GUI (for example, qApp.processEvents() for Qt), show progress, etc 
    print('refreshed') 

Если вы запустите следующий в этом сценарии,

data = list(range(100)) # your large data object 
list_pickler = ListSubPickler(data) 
SubList.on_pickling = refresh 

print('\ndumping pickle of', list_pickler) 
pickled = pickle.dumps(list_pickler) 

print('\nloading from pickle') 
new_list_pickler = pickle.loads(pickled) 
assert new_list_pickler.data == data 

print('\nloading from pickle, without on_pickling') 
SubList.on_pickling = None 
new_list_pickler = pickle.loads(pickled) 
assert new_list_pickler.data == data 

Вы увидите, что обновление обратного вызова вызывается 10 раз. Поэтому, если у вас есть список 2 ГБ для сбрасывания, и требуется 1 минута, чтобы свалить, так что вам понадобится обновить примерно 60 * 10 = 600 GUI, тогда вы должны установить количество блоков в 600.

Код легко изменен для dict, numpy array и т. д.

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