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

转储字典列表时出现Python pickle错误,python,recursion,pickle,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 "Canno

这是我的职责:

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 
当我对字典或列表进行pickle处理时,它可以很好地工作,但是它不能处理字典列表。我从另一个函数中获取一个作为
单记录的词典,然后将其附加到我的列表中:

def set_dict(url.....)
     single_record={'url':url,
                    'title':song_obj.getSongTitle(),
                    'name':song_obj.getPerformer(),
                    'author':song_obj.getAuthors(),
                    }
     return single_record
当我尝试转储50个dict的列表时,我得到以下错误:

maximum recursion depth exceeded
有人能帮你找出这有什么问题吗?

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

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

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

如果在pickle代码时抛出错误,那么很可能是您试图pickle的结构有太多嵌套元素。这是因为,
转储
/
转储
将在正在转储的结构中的容器上递归。也就是说,如果您正在转储一个列表,它将转储列表中的每个元素,这些元素本身可能是一个列表或dict,因此它将首先转储这些元素,依此类推。如果元素嵌套太深(列表或dict,其中包含列表或dict,当包含无限的列表或dict时),那么在某个点您将达到最大递归深度

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

我试着整理了1000个dict的列表(在结构上与你的类似),效果很好。因此,您可能无意中构建了一个嵌套过多的结构,或者调用
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()
不断提高它,直到得到正确的答案。如果你的结构过于嵌套,看看你是否能找到一种方法,通过不同的结构使它不那么嵌套


编辑:为了子孙后代的利益,修复了嵌套性,因此它可以处理空的dict和序列

注意,执行除异常之外的
是一个非常糟糕的主意,可能会隐藏代码中的其他问题。相反,只捕获特定的异常—在您的情况下,就是在文件无法打开时引发的异常。此外,当您遇到异常时,请发布整个堆栈跟踪,这将大大简化解决问题的过程。最后,当您使用
with
语句打开文件时,上下文管理器为您处理关闭文件的操作,您不需要手动关闭它。在最后的
返回中有另一个小的冗余-Python函数无论如何都会在最后返回,因此没有必要在那里添加它。谢谢,我同意这不是捕获的最佳方式,但我仍然打印错误(e),它说“超过了最大递归深度”,我在这里找不到递归问题。当我将限制提高到10000时,效果很好,谢谢!我仍然不明白你的结构最初是如何嵌套的,因为你发布的代码看起来不应该生成这样的嵌套结构。你应该确保在没有意识到的情况下,你不会不必要地嵌套东西,否则这个解决方案将被证明是脆弱的,并且在将来10000太低时会破裂。PS:如果这回答了您的问题,您应该将答案标记为已接受:)我也是,当我打印50条口述的列表时,它会显示以下50行:{'url':u','author':[],'name':'','title':u'\u05de\u05d5\u05e8\u05d9\u05dd\u05d9\u05e0\u05dd\u05de\u05e1\u05e4\u05e8\u05d9\u05dd'}嵌套()
在列表中调用时返回?顺便说一句,在
picklit()
的第一行中调用
data
,这样您就可以确定您正在测试正在被pickle的数据。当仅将此词典添加到列表[{'url':u','author':[]时,它失败并给出错误:“ValueError:max()arg是一个空序列”,“名称”:“标题”:u'\u05de\u05d5\u05e8\u05d9\u05dd\u05d0\u05d9\u05e0\u05dd\u05de\u05e1\u05e4\u05e8\u05d9\u05dd'}]