【问题标题】:Modular serialization with pickle (Python)带泡菜的模块化序列化(Python)
【发布时间】:2012-05-15 19:16:42
【问题描述】:

我想以模块化的方式执行一些对象图的序列化。那就是我不想序列化整个图。原因是这张图很大。我可以保留图表某些部分的时间戳版本,并且我可以做一些惰性访问来推迟加载我现在不需要的部分。

我认为我可以通过 Python 中的元编程来解决这个问题。但似乎 Python 中的元编程还不够强大。

这就是我现在要做的。我的图表由几个不同的对象组成。其中一些是特殊类的实例。此类描述要腌制的根对象。这就是模块化的用武之地。每次我腌制一些东西时,它都会从其中一个实例开始,我从不同时腌制其中两个。每当有对另一个实例的引用,根对象可以访问时,我用一个persistant_id 替换这个引用,从而确保我不会在同一个酸洗流中拥有它们中的两个。解封流时出现问题。我可以找到一个尚未加载的实例的persistant_id。在这种情况下,我必须等待目标实例被加载,然后才能访问它。而且我无论如何也看不到这样做:

1/ 我尝试构建一个 get 方法返回引用目标的访问器。不幸的是,访问器必须放在类声明中,我不能将它们分配给未腌制的对象。 2/我可以将引用必须解决的地方存储在某个地方。我认为这在 Python 中是不可能的:不能保留对位置(字段或变量)的引用,只能保留对值的引用。

我的问题可能不清楚。我仍在寻找一个清晰的配方。我尝试了其他方法,例如使用显式引用,这将是某些“引用”类的实例。不过也不是很方便。

你知道如何用 pickle 实现模块化序列化吗?我是否必须更改 Unpickler 的内部行为才能记住我需要加载剩余对象图的位置?是否有其他库更适合实现类似结果?

【问题讨论】:

    标签: python pickle


    【解决方案1】:

    我认为我会这样做。

    1. 有一个模块级字典将 persistent_id 映射到 SpecialClass 对象。每次初始化或取消选中 SpecialClass 实例时,请确保将其添加到字典中。

    2. 重写 SpecialClass 的 __getattr____setattr__ 方法,以便 specialobj.foo = anotherspecialobj 仅在 specialobj 的字典中存储一个 persistent_id(我们称之为 specialobj.specialrefs)。当您检索specialobj.foo 时,它会在specialrefs 中查找名称,然后在模块级字典中查找引用。

    3. 有一个模块级别的 check_graph 函数,该函数将遍历已知的 SpecialClass 实例并检查它们的所有特殊引用是否可用。

    【讨论】:

    • 问题在于它要求只有 Specialclass 实例才能拥有对其他实例的引用。这不是我的情况。例如,您的对象中不能有实例列表。
    【解决方案2】:

    元编程在 Python 中很强大; Python 类具有极强的延展性。您可以在声明后按照您想要的方式更改它们,尽管最好在元类(装饰器)中完成。不仅如此,实例具有可塑性,独立于它们的类。

    “对地点的引用”通常只是一个字符串。例如。对对象字段的引用是其名称。假设您的节点对象中有多个节点引用。您可以将{persistent_id: (object, field_name),..} 之类的内容作为未解决的参考表,便于查找。同样,在节点列表中,“对地点的引用”是索引。

    顺便说一句,您可以使用键值数据库进行图形存储吗?您无需等待即可按 ID 拉取节点。

    【讨论】:

    • 我不是 Python 专家。如何检索被腌制的字段的名称?为了回答您的问题,在我的例子中,每个“特殊类”实例都有一个唯一的整数 id,并且位于由扩展处理的键值数据库中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    相关资源
    最近更新 更多