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