转储字典列表时出现Python pickle错误

时间:2013-02-23 21:51:37

标签: python recursion pickle

这是我的功能:

def pickleIt(file_name,data):
   try:
        with open(file_name+".pickle", "wb") as output_file:
            pickle.dump(data, output_file,-1)
        output_file.close()
    except Exception,e:
        print "Cannot open the file:",file_name,e
    return 

当我挑选字典或列表时,它工作正常,但它不适用于字典列表。我从另一个函数中获取一个字典single_record,然后将其附加到我的列表中:

def set_dict(url.....)
     single_record={'url':url,
                    'title':song_obj.getSongTitle(),
                    'name':song_obj.getPerformer(),
                    'author':song_obj.getAuthors(),
                    }
     return single_record

当我尝试转储50个dicts的列表时,我收到以下错误: 超出最大递归深度。有人请帮忙找到错误的吗?

1 个答案:

答案 0 :(得分:2)

您获得的“超出最大递归深度”的错误意味着您的调用堆栈太深。调用堆栈的深度基本上是从初始调用点调用了多少函数(类似于主函数​​/循环),而不返回。

例如,如果从您的初始呼叫点开始呼叫func1()。在func1()中,深度当前为1.如果func1(),则在返回之前调用另一个函数,该函数中的深度将为2.

要了解调用堆栈调用sys.getrecursionlimit()的大小的当前限制,并更改它,请致电sys.setrecursionlimit()

如果在挑选代码时抛出错误,那么很可能,你试图挑选的结构是有太多的嵌套元素。这是因为,dump / dumps将递归被转储结构中的容器。这意味着,如果你要转储一个列表,它会转储列表中的每个元素,这些元素本身可能是一个列表或字典,因此它会首先转储那些元素,依此类推。如果元素嵌套太深(列表或字母,包含列表或字典,当包含列表或无条件时无限制),那么在某些时候,您将达到最大递归深度。

问题可能在其他地方,但没有任何进一步的细节,这是唯一可能导致的事情(如果确实是错误被抛出的地方)。

我已经尝试过挑选1000个dicts的列表(结构与你的相似)并且它运行得很好。因此,要么您无意中构建了一个嵌套太多的结构,要么在调用picke.dump()

时不会抛出错误

编辑:

尝试使用此函数来查看您尝试转储的结构是如何嵌套的:

def nestedness(struct):
    if isinstance(struct, list):
        return max([0] + [nestedness(i) for i in struct]) + 1
    if isinstance(struct, dict):
        return max([0] + [nestedness(i) for i in struct.values()])+1
    return 1

如果超过最大递归深度失败,请继续使用sys.setrecursionlimit()进行提升,直到得到正确的答案。如果你的结构太嵌套了,看看你是否可以通过不同的结构来找到一种方法来减少结构。

编辑:为了后人的缘故,修复了嵌套,以便处理空的dicts和序列