在 python 开发中,我们经常使用 raise 抛出异常来处理错误情况。但有时候,异常信息中的中文或其他非 ascii 字符会被显示为 unicode 转义序列(如 \u6b63\u6587),而不是直接显示中文(如“正文”)。这不仅影响可读性,还可能让调试变得困难。本文将详细分析这个问题,并提供解决方案。
1. 问题重现
1.1 示例代码
假设我们有一个函数 check_paragraph_order(),用于检查文档段落编号是否正确排序。如果发现异常,则抛出异常并附带错误信息:
import json
def get_paragraph_info():
# 模拟返回段落信息(包含中文)
return {
"type": "paragraph",
"index": 179,
"content": "(1)建设业务经营:形成“国内+国际+新基建”三轮驱动;",
"label": ["正文"]
}
def check_paragraph_order():
paragraph_info = get_paragraph_info()
# 模拟检查失败,抛出异常
raise exception(json.dumps({
'error_msg': '正文编号排序异常',
'detail_msg': paragraph_info
}))
try:
check_paragraph_order()
except exception as e:
print(f"捕获到异常: {e}")
1.2 运行结果
运行上述代码后,控制台输出:
捕获到异常: {"error_msg": "\u6b63\u6587\u7f16\u53f7\u6392\u5e8f\u5f02\u5e38", "detail_msg": {"type": "paragraph", "index": 179, "content": "\uff081\uff09\u5efa\u8bbe\u4e1a\u52a1\u7ecf\u8425\uff1a\u5f62\u6210\u201c\u56fd\u5185+\u56fd\u9645+\u65b0\u57fa\u5efa\u201d\u4e09\u8f6e\u9a71\u52a8\uff1b", "label": ["\u6b63\u6587"]}}
可以看到:
error_msg中的“正文编号排序异常”被显示为\u6b63\u6587...。detail_msg中的中文也被转义为 unicode 编码。
2. 问题原因
2.1json.dumps()默认行为
json.dumps()是 python 中将字典转换为 json 字符串的方法。- 默认情况下,
json.dumps()会将所有非 ascii 字符(如中文、日文、韩文等)转义为 unicode 编码(如\u6b63)。 - 这是 json 规范的一部分,目的是确保 json 字符串在所有环境中都能安全传输(避免编码问题)。
2.2 控制台打印时的显示
- 当我们
print(exception(...))或捕获异常后打印时,python 会调用str()方法,而exception的str()方法会直接显示json.dumps()的结果(包含 unicode 转义)。 - 因此,控制台看到的是
\u6b63\u6587...,而不是直接显示中文。
3. 解决方案
3.1 方法 1:使用ensure_ascii=false
最简单的方法是在 json.dumps() 中添加参数 ensure_ascii=false,强制保留非 ascii 字符(如中文):
raise exception(json.dumps({
'error_msg': '正文编号排序异常',
'detail_msg': get_paragraph_info()
}, ensure_ascii=false))
运行结果:
捕获到异常: {"error_msg": "正文编号排序异常", "detail_msg": {"type": "paragraph", "index": 179, "content": "(1)建设业务经营:形成“国内+国际+新基建”三轮驱动;", "label": ["正文"]}}
优点:
- 直接显示中文,可读性高。
- 保留 json 结构的机器可读性。
适用场景:需要异常信息既可读又可被程序解析时。
3.2 方法 2:手动解析 json 字符串(不推荐)
如果无法修改 json.dumps() 的调用,可以捕获异常后手动解析 json 字符串:
try:
check_paragraph_order()
except exception as e:
error_json = str(e) # 获取 json 字符串(含 unicode)
error_dict = json.loads(error_json) # 解析 json 回字典
print(f"错误信息: {error_dict['error_msg']}") # 直接访问中文字段
运行结果:
错误信息: 正文编号排序异常
缺点:
- 代码冗余,需要额外解析 json。
- 仅适用于简单场景,不推荐广泛使用。
3.3 方法 3:直接构造错误信息(避免 json 转换)
如果错误信息不需要 json 结构,可以直接用字符串拼接:
def check_paragraph_order():
paragraph_info = get_paragraph_info()
error_msg = f"正文编号排序异常,详情: {paragraph_info}"
raise exception(error_msg)
运行结果:
捕获到异常: 正文编号排序异常,详情: {'type': 'paragraph', 'index': 179, 'content': '(1)建设业务经营:形成“国内+国际+新基建”三轮驱动;', 'label': ['正文']}
优点:
- 简单直接,无需 json 转换。
- 适用于错误信息不需要机器解析的场景。
缺点:丢失 json 结构,不利于程序化处理。
4. 最佳实践
| 方案 | 适用场景 | 推荐指数 |
|---|---|---|
| json.dumps(..., ensure_ascii=false) | 需要异常信息既可读又可被程序解析 | ⭐⭐⭐⭐⭐ |
| 手动解析 json 字符串 | 无法修改 json.dumps() 调用 | ⭐⭐ |
| 直接构造错误信息 | 错误信息不需要 json 结构 | ⭐⭐⭐ |
推荐方案:
- 优先使用
ensure_ascii=false,因为它既保留了 json 结构,又让中文直接显示。 - 如果错误信息不需要 json 结构,可以直接用字符串拼接。
5. 总结
问题原因:json.dumps() 默认转义非 ascii 字符(如中文)为 unicode 编码。
解决方案:
ensure_ascii=false(推荐):强制保留中文,直接显示。- 手动解析 json(不推荐):适用于无法修改源码的情况。
- 直接构造字符串:适用于简单错误信息。
最佳实践:优先使用 ensure_ascii=false,兼顾可读性和机器可解析性。
6. 完整代码示例
import json
def get_paragraph_info():
return {
"type": "paragraph",
"index": 179,
"content": "(1)建设业务经营:形成“国内+国际+新基建”三轮驱动;",
"label": ["正文"]
}
def check_paragraph_order():
paragraph_info = get_paragraph_info()
# 使用 ensure_ascii=false 保留中文
raise exception(json.dumps({
'error_msg': '正文编号排序异常',
'detail_msg': paragraph_info
}, ensure_ascii=false))
try:
check_paragraph_order()
except exception as e:
print(f"捕获到异常: {e}")
运行结果:
捕获到异常: {"error_msg": "正文编号排序异常", "detail_msg": {"type": "paragraph", "index": 179, "content": "(1)建设业务经营:形成“国内+国际+新基建”三轮驱动;", "label": ["正文"]}}
到此这篇关于python使用raise报错抛出异常显示unicode码的解决方法的文章就介绍到这了,更多相关python raise报错显示unicode码解决内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论