为何json.dumps()与json.loads()会生成unicode字符串?
为什么
json.dumps()与json.loads()会生成unicode字符串? 这个问题在Python 2环境下非常常见,我来帮你拆解原因和解决办法:
核心原因
首先要明确:JSON规范中的字符串本质是Unicode编码,而Python 2的标准json模块在处理序列化/反序列化时,默认遵循这个映射规则:
json.dumps()会把Python的str(字节串)序列化为符合JSON规范的字符串;json.loads()解析JSON字符串时,会将其转换为Python的unicode类型——这是模块的默认行为,目的是保证文本的Unicode兼容性,避免编码混乱。
你的代码里,虽然通过myconverter把datetime对象转成了str,但经过json.dumps()序列化再json.loads()反序列化后,所有字符串类型的字段(比如tweet、转换后的created_at)都会被自动转为unicode。
解决办法
根据你的需求,有几种可行的处理方式:
1. 优先接受unicode类型(推荐)
在Python 2中,unicode是专门用于处理文本的类型,比str更安全——尤其是你的tweet包含特殊符号和话题标签,用unicode可以避免后续出现编码错误。如果你的业务代码能兼容unicode,这是最优选择。
2. 手动将unicode转换为str
如果你必须得到str类型,可以在loads之后遍历字典,把所有unicode值转换为str(注意指定编码,推荐用utf-8):
import json import datetime def myconverter(o): if isinstance(o, datetime.datetime): return o.isoformat() # 用ISO标准格式替代__str__,更规范 def unicode_to_str(obj): if isinstance(obj, dict): return {unicode_to_str(key): unicode_to_str(value) for key, value in obj.items()} elif isinstance(obj, unicode): return obj.encode('utf-8') else: return obj # 模拟你的数据 message_value = { 'created_at': datetime.datetime(2018, 5, 25, 13, 35, 11), 'tweet': "RT @KKRiders: Mavi to bowl the first ball of #Qualifier2. Saha on strike. Let's go!\n#SRHvKKR #TeesraVaar #KKRHaiTaiyaar", 'id': 1000007371131764736, 'sequence': 1 } messageRead = json.dumps(message_value, default=myconverter) messageRead = json.loads(messageRead) messageRead_str = unicode_to_str(messageRead) print(messageRead_str) print(type(messageRead_str['tweet'])) # 输出 <type 'str'>
3. 升级到Python 3(根源解决)
在Python 3里,str类型本身就是Unicode编码的,json.loads()返回的字符串直接是str,不存在unicode和str的区分问题,能从根源上解决这类编码困扰。
另外补充个小优化:你的myconverter用o.__str__()转换datetime,推荐换成o.isoformat(),生成的是标准ISO时间字符串,可读性更好也更符合JSON的时间表示习惯。
内容的提问来源于stack exchange,提问作者hasherBaba
相关产品推荐
相关产品推荐

