0

我正在考虑使用数量来定义一个数字及其单位。该值很可能必须存储在磁盘上。您可能知道,pickling 有一个主要问题:如果您重新定位模块,unpickling 将无法解析类,并且您将无法 unpickle 信息。这种行为有一些解决方法,但它们确实是解决方法。

我为这个问题设想的一个解决方案是创建一个给定单元唯一的字符串编码。一旦你从磁盘获得了这个编码,你就将它传递给 Quantities 模块中的一个工厂方法,该方法将它解码为一个适当的单元实例。好处是即使你重新定位模块,只要你将魔法字符串令牌传递给工厂方法,一切仍然有效。

这是一个已知的概念吗?

4

1 回答 1

1

看起来像是惠勒第一原理的应用,“计算机科学中的所有问题都可以通过另一个间接层次来解决”(第二原理添加了“但这通常会产生另一个问题”;-)。本质上,您需要做的是间接识别类型- 类型内的实体将适用于类似酸洗的方法(您可以研究后者的来源pickle.pycopy_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——绕过所有注册问题。我认为您认为这是一种“解决方法”,但对我来说,这似乎只是“多一层间接”概念的一种极其简单、强大且方便的实现,它避免了“多一个问题”的问题;-)。

于 2009-08-25T15:08:48.177 回答