2009-08-25 3 views
0

Я рассматриваю использование Quantities для определения числа вместе с его устройством. Это значение, скорее всего, должно быть сохранено на диске. Как вы, вероятно, знаете, травление имеет одну серьезную проблему: если вы перемещаете модуль вокруг, рассыпание не сможет разрешить класс, и вы не сможете распечатать эту информацию. Для такого поведения существуют обходные пути, но они действительно являются обходными решениями.Стабильная сериализация python (например, проблемы с перемещением модуля рассола)

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

Является ли это известной концепцией?

ответ

1

Похоже, что применение первого принципа Уилера «все проблемы в информатике могут быть решены другим уровнем косвенности» (второй принцип добавляет «но это обычно создает другую проблему» ;-). По существу, вам нужно указать направление типа. Сущность внутри класса будет в порядке с подходами, подобными травлению (вы можете изучить источники pickle.py и copy_reg.py для всех мелких деталей последних).

В частности, я считаю, что то, что вы хотите сделать, это подкласс pickle.Pickler и переопределить метод save_inst. Если текущая версия говорит:

if self.bin: 
     save(cls) 
     for arg in args: 
      save(arg) 
     write(OBJ) 
    else: 
     for arg in args: 
      save(arg) 
     write(INST + cls.__module__ + '\n' + cls.__name__ + '\n') 

вы хотите написать что-то другое, чем просто модуля и имя класса - своего рода уникальный идентификатор (состоящий из двух строки) для класса, вероятно, состоится в собственном реестре или реестров; и аналогично для метода save_global.

Это даже проще для подкласса Unpickler, потому что _instantiate часть уже вынесена в отдельный метод: вам нужно только переопределить find_class, который:

def find_class(self, module, name): 
    # Subclasses may override this 
    __import__(module) 
    mod = sys.modules[module] 
    klass = getattr(mod, name) 
    return klass 

он должен взять две строки и возврат объект класса; вы можете сделать это через свои реестры, снова.

Как всегда, когда реестры участвуют, вам нужно подумать о том, как обеспечить регистрацию всех интересующих объектов (классов) и т. Д. И т. Д. Одна из популярных стратегий заключается в том, чтобы оставить травление в одиночку, но обеспечить, чтобы все ходы классов , переименования модулей и т. д., записываются где-то постоянным; таким образом, только подклассовый неуправляемый может выполнять всю работу, и он может наиболее удобно сделать все это в переопределенном find_class - обходя все проблемы регистрации. Полагаю, вы считаете это «обходным путем», но для меня это просто простое, мощное и удобное воплощение концепции «еще один уровень косвенности», которая позволяет избежать проблемы «еще одной проблемы» ;-).

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