Похоже на применение Первого принципа Уилера, «все проблемы в информатике могут быть решены с помощью другого уровня косвенности» (второй принцип добавляет «но это обычно создает другую проблему» ;-). По сути, вам нужно косвенное указание для определения типа - сущность внутри типа будет в порядке с подходами, подобными маринованию (вы можете изучить источники 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
- минуя все вопросы регистрации. Я полагаю, вы считаете это «обходным путем», но мне кажется, что это просто чрезвычайно простая, мощная и удобная реализация концепции «еще одного уровня косвенности», которая позволяет избежать проблемы «еще одной проблемы»; -).