看起来像是惠勒第一原理的应用,“计算机科学中的所有问题都可以通过另一个间接层次来解决”(第二原理添加了“但这通常会产生另一个问题”;-)。本质上,您需要做的是间接识别类型- 类型内的实体将适用于类似酸洗的方法(您可以研究后者的来源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
它必须接受两个字符串并返回一个类对象;您可以再次通过您的注册表执行此操作。
像往常一样,当涉及到注册表时,您需要考虑如何确保注册所有感兴趣的对象(类)等。这里一种流行的策略是不理会腌制,但要确保类的所有移动,模块的重命名等,被记录在永久的地方;这样,只有子类的 unpickler 可以完成所有工作,并且它可以最方便地在覆盖的情况下完成所有工作find_class
——绕过所有注册问题。我认为您认为这是一种“解决方法”,但对我来说,这似乎只是“多一层间接”概念的一种极其简单、强大且方便的实现,它避免了“多一个问题”的问题;-)。