一篇文章搞懂Python反斜杠的相关问题
本文深入解析Python中json.dumps多次序列化导致的反斜杠倍增现象。通过字典转JSON字符串再转JSON字符串的示例,解释Unicode编码、转义字符及双引号冲突原理。强调处理此类数据时,应使用json.loads逐层还原,而非简单的字符串替换,避免数据解析错误。
Python反斜杠问题的引入
在Python开发实践中,反斜杠相关的问题频发,许多开发者常因反斜杠数量的变化而感到困惑。
JSON序列化与反斜杠的产生
我们先看一段简单的Python代码,其功能是将一个字典对象先序列化为JSON格式的字符串,随后再次将该字符串序列化为JSON字符串。
import json
info = {'name': 'kingname', 'address': '杭州', 'salary': 99999}
info_json = json.dumps(info)
# 第一次转换以后,打印出来
print(info_json)
info_json_json = json.dumps(info_json)
# 第二次转换以后,再打印出来
print(info_json_json)
代码运行结果如图所示。

第一次转换中,字典转为JSON字符串,仅中文“杭州”被转换为Unicode编码\u676d\u5dde,其他部分未出现反斜杠。
在Python语法中,反斜杠不能单独存在。此处\u676d\u5dde显示的两根反斜杠,实际代表的是\u。这表示该编码属于Unicode编码格式。
接着,将第一次生成的JSON字符串:{"name": "kingname", "address": "\u676d\u5dde", "salary": 99999}再次进行JSON序列化,结果变为:
"{\"name\": \"kingname\", \"address\": \"\\u676d\\u5dde\", \"salary\": 99999}"
反斜杠倍增的原理分析
为何此时出现了大量反斜杠?原因在于JSON字符串使用双引号界定字符串内容。若原字符串内部包含双引号,会造成解析歧义。此时,Python需将原字符串中的双引号转为普通字符,使其失去界定作用,因此使用\"对双引号进行转义。
这类似于在Python中定义包含双引号的字符串的方式:
>>> a = "跟我说:\"你好\""
>>> print(a)
跟我说:"你好"
此处,“你好”两侧的双引号均添加了反斜杠,使其成为普通字符,防止其提前与外层双引号匹配。
若不加反斜杠,字符串内部的双引号会提前与外层双引号配对,引发语法错误:
>>> b = "跟我说:"你好""
File "<stdin>", line 1
b = "跟我说:"你好""
^
SyntaxError: invalid syntax
这里,"跟我说:"被视为一个字符串,末尾的""被视为空字符串。中间的“你好”则被当作未定义的变量。由于Python不支持字符串未定义的变量字符串这种写法,故报错。
JSON字符串本质也是字符串,自然需遵循此规则。因此,字符串原本自带的双引号左侧会被添加反斜杠。
那么,原来的\u676d\u5dde为何变成了\\u676d\\u5dde?
这是因为,当第二次执行json.dumps时,传入参数为JSON字符串,本质仍是字符串。若字符串内部自带反斜杠,JSON在再次转换时需标记其为普通字符串形式的反斜杠,而非特殊意义字符,故使用\\表示普通反斜杠。
那么,如果将info_json_json再次执行json.dumps操作,结果会如何?
结果将变为:
"\"{\\\"name\\\": \\\"kingname\\\", \\\"address\\\": \\\"\\\\u676d\\\\u5dde\\\", \\\"salary\\\": 99999}\""
为何会出现三个反斜杠连用及四个反斜杠连用的情况?
原理其实很简单,当对info_json_json执行json.dumps时,Python是如何进行转换的?
我们来看具体过程:
"{\"name\": \"kingname\", \"address\": \"\\u676d\\u5dde\", \"salary\": 99999}"
对字符串执行json.dumps时,需记住关键方法——从左到右,逐个字符进行转换。
1. 第一个字符是双引号,转换为\" 2. 第二个字符是{,非特殊符号,保留 3. 第三个字符是\,转换为\\ 4. 第四个字符是",转换为\" 5. ……
全部转换完成后,由于此次操作是将字符串转换为JSON格式字符串,因此最外侧会加上双引号。
最终得到:
"\"{\\\"name\\\": \\\"kingname\\\", \\\"address\\\": \\\"\\\\u676d\\\\u5dde\\\", \\\"salary\\\": 99999}\""
正确处理多层JSON字符串的方法
在爬虫开发中,可能会遇到上述经过多次JSON转换后的字符串。此时,切勿轻易使用字符串的.replace方法将多个反斜杠替换为空,或将两个反斜杠替换为一个。这种做法只会让数据更难解析。
正确做法是尝试对数据逐层使用json.loads,将其一层层还原,直至恢复为最初的{'name': 'kingname', 'address': '杭州', 'salary': 99999}这种简单形式。
调试模式下的反斜杠观察
今天的介绍到此结束,最后留一个思考题:
仍使用上述代码,现在打开PyCharm的调试模式,然后数一数info_json和info_json_json中反斜杠的数量,如下图所示:

为何在info_json中,出现了\\u676d\\u5dde?为何在info_json_json中双引号前是两根反斜杠,而\"\\u676d\\u5dde\"竟然变成了\\"\\\\u676d\\\\u5dde?
总结
至此,关于Python反斜杠的讲解结束。更多相关Python反斜杠内容,请搜索本站以往文章或继续浏览下文。感谢大家的支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









