Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
463 views
in Technique[技术] by (71.8m points)

python - json.dump throwing "TypeError: {...} is not JSON serializable" on seemingly valid object?

Background: I am writing a python program which should manage my music files. It crawls directories and puts the files and their meta data (via mutagen), encoded in JSON, in a file as a simple "database". I have the directory searching fine, but when I try and save the database, or encode to JSON, it throws a "TypeError: {...} is not JSON serializable" (the ... are some keys and values from a dict, more on that below)

The Problem: The program builds a large dictionary object following this format:

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

Every single song file is indexed via this format. When I try to dump the database to a file, I get this:

Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    sit()
  File "D:workbenchideasmusicmanagerv0spider.py", line 116, in sit
    json.dump(js.db,f,True)
  File "C:Python27libjson\__init__.py", line 181, in dump
    for chunk in iterable:
  File "C:Python27libjsonencoder.py", line 428, in _iterencode
    for chunk in _iterencode_dict(o, _current_indent_level):
  File "C:Python27libjsonencoder.py", line 402, in _iterencode_dict
    for chunk in chunks:
  File "C:Python27libjsonencoder.py", line 402, in _iterencode_dict
    for chunk in chunks:
  File "C:Python27libjsonencoder.py", line 436, in _iterencode
    o = _default(o)
  File "C:Python27libjsonencoder.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

With the key for that particular song entry being

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

(the format for the id is a little bulky, I might end up hashing that...)

So I tried to

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

which worked fine, as did

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

And then I tried this:

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

Which failed with the type error again.

Why does that object fail with json.dump? I have plenty of other objects with keys containing pipes "|" and apostrophes "'"... At the moment, I have no way for anyone else to test this, should I post a pickled version of the database object?

Additional Notes

  • The resulting object below json.dumps is fine, so I am wondering if the issue has to do with the size of the database in any way?

    {rooney:js.db['songsbyid'][rooney]} {"Rooney|Rooney's Lost Album|The Kids After Sunset|The Kids After Sunset.itunes.mp3": {'album': [u"Rooney's Lost Album"], 'title': [u'The Kids After Sunset'], 'artist': [u'Rooney']}}

  • If I exclude the song by renaming the extension so the script ignores it, another arbitrary song causes the same error. I renamed&excluded this new song, and ran into ANOTHER new song... I don't know how many there are.

  • I changed my program to crawl the next furthest sub-directory containing the original problem song, and json.dump raised a TypeError on a completely different song...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Because it's not actually a dictionary; it's another mapping type that looks like a dictionary. Use type() to verify. Pass it to dict() to get a real dictionary from it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...