json.dump抛出“TypeError:{…}是不是JSON序列化”看似有效的对象?

背景 :我正在写一个应该pipe理我的音乐文件的Python程序。 它抓取目录,并将文件和它们的元数据(通过mutagen)编码成JSON格式,作为一个简单的“数据库”。 我有目录search很好,但是当我尝试保存数据库,或编码为JSON,它会引发“TypeError:{…}不是JSON可序列化”(…是一些字典和键值,下面更多)

问题 :程序按照以下格式构build一个大的字典对象:

{ "<song id>":{ "artist":"<song artist>", "album":"<song album>", "title":"<song title>"}, ... } 

每一首歌曲文件都通过这种格式进行索引。 当我尝试将数据库转储到一个文件,我得到这个:

 Traceback (most recent call last): File "<pyshell#2>", line 1, in <module> sit() File "D:\workbench\ideas\musicmanager\v0\spider.py", line 116, in sit json.dump(js.db,f,True) File "C:\Python27\lib\json\__init__.py", line 181, in dump for chunk in iterable: File "C:\Python27\lib\json\encoder.py", line 428, in _iterencode for chunk in _iterencode_dict(o, _current_indent_level): File "C:\Python27\lib\json\encoder.py", line 402, in _iterencode_dict for chunk in chunks: File "C:\Python27\lib\json\encoder.py", line 402, in _iterencode_dict for chunk in chunks: File "C:\Python27\lib\json\encoder.py", line 436, in _iterencode o = _default(o) File "C:\Python27\lib\json\encoder.py", line 178, in default raise TypeError(repr(o) + " is not JSON serializable") TypeError: {'album': [u"Rooney's Lost Album"], 'title': [u'The Kids After Sunset'], 'artist': [u'Rooney']} is not JSON serializable 

随着特定的歌曲条目的关键

 Rooney|Rooney's Lost Album|The Kids After Sunset|The Kids After Sunset.itunes.mp3 

(这个ID的格式有点笨重,我可能最终会哈希…)

所以我试着去

 json.dumps({'album': [u"Rooney's Lost Album"], 'title': [u'The Kids After Sunset'], 'artist': [u'Rooney']}) 

哪个工作得很好

 json.dumps({"Rooney|Rooney's Lost Album|The Kids After Sunset|The Kids After Sunset.itunes.mp3":""}) 

然后我尝试了这个:

 rooney = "Rooney|Rooney's Lost Album|The Kids After Sunset|The Kids After Sunset.itunes.mp3" json.dumps({rooney:js.db['songsbyid'][rooney]}) 

其中的types错误再次失败。

为什么该对象失败与json.dump? 我有大量的其他对象与包含pipe道的键“|” 和撇号“'”…目前,我没有办法让其他人来testing这个,我应该发布一个数据库对象的腌制版本?

补充笔记

  • 在json.dumps下面的结果对象是好的,所以我想知道如果问题以任何方式与数据库的大小?

    {rooney:js.db ['songsbyid'] [rooney]} {“Rooney | Rooney's Lost Album |日落后的孩子们| Sunset.itunes.mp3后的孩子们:{'album':[ ],'title':[u'The Children After Sunset'],'artist':[u'Rooney']}}

  • 如果我通过重命名扩展名排除歌曲,脚本忽略它,另一个任意的歌曲会导致相同的错误。 我重新命名并排除了这首新歌,并且跑进了另一首新歌…我不知道有多less歌。

  • 我改变了我的程序来抓取包含原始问题歌曲的下一个最远的子目录,并且json.dump在完全不同的歌曲上引发了TypeError。

因为它实际上不是一本字典; 这是另一种类似字典的映射types。 使用type()来validation。 把它传给dict()从中得到一个真正的字典。

我写了一个类来规范我的字典中的数据。 下面的NormalizeData类中的'元素'需要是字典types。 你需要用__iterate()replace你自定义的类对象或者你想要规范化的任何其他对象types。

 class NormalizeData: def __init__(self, element): self.element = element def execute(self): if isinstance(self.element, dict): self.__iterate() else: return def __iterate(self): for key in self.element: if isinstance(self.element[key], <ClassName>): self.element[key] = str(self.element[key]) node = NormalizeData(self.element[key]) node.execute()