【发布时间】:2012-06-08 00:18:08
【问题描述】:
背景:我正在编写一个 python 程序来管理我的音乐文件。它爬取目录并将文件及其元数据(通过诱变剂)以 JSON 编码,作为简单的“数据库”放入文件中。我的目录搜索很好,但是当我尝试保存数据库或编码为 JSON 时,它会抛出“TypeError:{...} is not JSON serializable” (... 是 dict 中的一些键和值,更多内容见下文)
问题:程序按照以下格式构建一个大型字典对象:
{
"<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]})
再次失败并出现类型错误。
为什么该对象会因 json.dump 而失败?我有很多其他对象,其键包含管道“|”和撇号“'”...目前,我无法让其他人对此进行测试,我应该发布数据库对象的腌制版本吗?
附加说明
-
json.dumps 下面的结果对象很好,所以我想知道这个问题是否与数据库的大小有关?
{鲁尼:js.db['songsbyid'][鲁尼]} {“鲁尼|鲁尼丢失的专辑|日落后的孩子们|孩子们 在 Sunset.itunes.mp3": {'album': [u"Rooney's Lost Album"] 之后, 'title': [u'The Kids After Sunset'], 'artist': [u'Rooney']}}
如果我通过重命名扩展名来排除歌曲以便脚本忽略它,另一首任意歌曲会导致相同的错误。我重命名&排除了这首新歌,又遇到了另一首新歌……不知道有多少。
我更改了我的程序以爬取包含原始问题歌曲的下一个最远的子目录,而 json.dump 在完全不同的歌曲上引发了 TypeError...
【问题讨论】:
-
您是否考虑过打印出来的内容可能不是它试图编码的内容?如果
db类定义了__repr__,您可能会看到一些看起来可以JSON 的东西被打印出来,但它试图编码的实际东西并不是这样。 -
谢谢@Amber,这不是我的数据库字典,它原来是歌曲元数据的诱变剂返回值
-
使用
json.dumps(data, default=lambda x: None)来抑制TypeErrors 并转储data中无法序列化为null的任何内容