2012-06-11 47 views
4

我有(从http.server使用类)写在Python3一个简单的Web服务器我是从2移植到3Python3 json.dumps给出了类型错误:键必须是一个字符串

我有以下代码:

# More code here... 
postvars = cgi.parse_qs(self.rfile.read(length), 
         keep_blank_values=1) 
something.json_run(json.dumps(postvars)) 

会抛出:

TypeError: keys must be a string 

通过检查数据,我已经确定parse_qs似乎编码键作为字节,这是什么扔ERR或者(json显然不喜欢字节)。

import json 
json.dumps({b'Throws error' : [b"Keys must be a string"]}) 
json.dumps({'Also throws error': [b'TypeError, is not JSON serializable']}) 
json.dumps({'This works': ['No bytes!']}) 

这里最好的解决方案是什么?在Python 2中,代码工作正常,因为parse_qs使用str而不是bytes。我最初的想法是,我可能需要编写一个JSON序列化程序。并不是说这对于简单的事情来说很困难,但我不希望我能够以其他方式做到这一点(例如,将字典翻译为使用字符串而不是字节)。

+1

python 2中的'str'实际上与'bytes'相同。 JSON库在Python 3中变得更挑剔(有理由)。 –

+0

所以我正在发现...:P –

+1

另请参阅:http://bit.ly/unipain – Daenyth

回答

2

首先,cgi.parse_qs函数已被弃用,只是urllib.parse.parse_qs的别名,您可能需要调整导入路径。

其次,你传递一个字节字符串到解析方法。如果你在一个正常(Unicode)的字符串传递而不是parse_qs方法返回的字符串规则:

>>> from urllib.parse import parse_qs 
>>> parse_qs(b'a_byte_string=foobar') 
{b'a_byte_string': [b'foobar']} 
>>> parse_qs('a_unicode_string=foobar') 
{'a_unicode_string': ['foobar']} 

因此,您需要将您的文件读取字节的字符串解码首先到正规的字符串。

相关问题