python - 用循环 pickle 图表

标签 python graph pickle

我在 python 中有一个自定义节点类,它内置在一个图形(它是一个字典)中。由于创建这些需要一些时间,我想对它们进行 pickle,这样我就不必在每次运行代码时都重建它们。

不幸的是,因为这个图有循环,cPickle 达到了最大递归深度:

RuntimeError: maximum recursion depth exceeded while pickling an object

这是我的节点对象:

class Node:
    def __init__(self, name):
        self.name = name
        self.uid = 0
        self.parents = set()
        self.children = set()

    def __hash__(self):
        return hash(self.name)

    def __eq__(self, that):
        return self.name == that.name

    def __str__(self):
        return "\n".join(["Name: " + self.name,
                          "\tChildren:" + ", ".join([c.name for c in self.children]),
                          "\tParents:" + ", ".join([p.name for p in self.parents])
                          ]
                         )

这就是我构建图表的方式:

def buildGraph(input):
    graph = {}
    idToNode = {}

    for line in input:
        ## Input from text line by line looks like
        ## source.node -> target.node
        source, arr, target = line.split()
        if source in graph:
            nsource = graph[source]
        else:
            nsource = Node(source)
            nsource.uid = len(graph)
            graph[source] = nsource
            idToNode[nsource.uid] = nsource

        if target in graph:
            ntarget = graph[target]
        else:
            ntarget = Node(target)
            ntarget.uid = len(graph)
            graph[target] = ntarget
            idToNode[ntarget.uid] = ntarget

        nsource.children.add(ntarget)
        ntarget.parents.add(nsource)
    return graph

然后在我的主要,我有

    graph = buildGraph(input_file)
    bo = cPickle.dumps(graph)

第二行是我得到递归深度错误的地方。

除了改变Node的结构,还有什么解决办法吗?

最佳答案

您需要为 pickle 准备对象:如果您有一个循环,您需要打破循环并以其他形式存储此信息。

Pickle 使用方法 __getstate__ 准备要 pickle 的对象(它之前调用)和 __setstate__ 初始化对象。

class SomethingPickled(object):
    ## Compress and uncycle data before pickle.
    def __getstate__(self):
        # deep copy object
        state = self.__dict__.copy()
        # break cycles
        state['uncycled'] = self.yourUncycleMethod(state['cycled'])
        del state['cycle']
        # send to pickle
        return state

    ## Expand data before unpickle.
    def __setstate__(self, state):
        # restore cycles
        state['cycle'] = self.yourCycleMethod(state['uncycled'])
        del state['uncycle']
        self.__dict__.update(state)

我相信你会找到如何打破和加入循环的想法:)

关于python - 用循环 pickle 图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9400908/

相关文章:

algorithm - 为图中的每个节点计算距离 n 处的未访问节点

python - 在 python 中使用 igraph 创建无向加权图

python - Unpickle 有时会生成空白对象

python - pickle 比使用数字数据的 cPickle 更快?

python django 无法让任何 View 工作

Python - 如何重新启动 for 循环?

java - 与 JUNG 库合作

python - 你可以在追加模式下使用pickle吗

python - 执行 pygame 时提高性能?

python - 如何在 Spyder 编辑器中使用 IPython 魔术命令?