Python 使用 `raise` 报错抛出异常显示 Unicode 码如何解决

在 Python 开发中,我们经常使用 raise 抛出异常来处理错误情况。但有时候,异常信息中的中文或其他非 ASCII 字符会被显示为 Unicode 转义序列(如 \u6b63\u6587),而不是直接显示中文(如"正文")。这不仅影响可读性,还可能让调试变得困难。本文将详细分析这个问题,并提供解决方案。


1. 问题重现

1.1 示例代码

假设我们有一个函数 check_paragraph_order(),用于检查文档段落编号是否正确排序。如果发现异常,则抛出异常并附带错误信息:

python 复制代码
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.1 json.dumps() 默认行为

  • json.dumps() 是 Python 中将字典转换为 JSON 字符串的方法。
  • 默认情况下json.dumps() 会将所有非 ASCII 字符(如中文、日文、韩文等)转义为 Unicode 编码(如 \u6b63)。
  • 这是 JSON 规范的一部分,目的是确保 JSON 字符串在所有环境中都能安全传输(避免编码问题)。

2.2 控制台打印时的显示

  • 当我们 print(Exception(...)) 或捕获异常后打印时,Python 会调用 str() 方法,而 Exceptionstr() 方法会直接显示 json.dumps() 的结果(包含 Unicode 转义)。
  • 因此,控制台看到的是 \u6b63\u6587...,而不是直接显示中文。

3. 解决方案

3.1 方法 1:使用 ensure_ascii=False

最简单的方法 是在 json.dumps() 中添加参数 ensure_ascii=False,强制保留非 ASCII 字符(如中文):

python 复制代码
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 字符串:

python 复制代码
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 结构,可以直接用字符串拼接:

python 复制代码
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 编码。
  • 解决方案
    1. ensure_ascii=False(推荐):强制保留中文,直接显示。
    2. 手动解析 JSON(不推荐):适用于无法修改源码的情况。
    3. 直接构造字符串:适用于简单错误信息。
  • 最佳实践 :优先使用 ensure_ascii=False,兼顾可读性和机器可解析性。

6. 完整代码示例

python 复制代码
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": ["正文"]}}

7. 扩展阅读

希望本文能帮助你解决 Python 异常信息显示 Unicode 码的问题!🚀

相关推荐
Evand J2 分钟前
【代码介绍】自适应R的AEKF(自适应扩展卡尔曼滤波)和经典EKF比较,MATLAB例程|三维非线性系统
开发语言·matlab·ekf·自适应·自适应滤波
曾阿伦2 分钟前
Unicode 正则表达式开发指南
python·正则表达式
香辣西红柿炒蛋5 分钟前
yaml文件介绍、数据读取
python
乐于分享的阿乐7 分钟前
(二)VSCode搭建python环境(详细图文保姆级教程)
ide·vscode·python
雪的季节9 分钟前
1 个网络线程 + 3 个数据处理线程(完全隔离)
开发语言
weixin_4080996710 分钟前
2026 AI生成图片快速去水印的5种实测方法(附在线工具 + Python/Java/PHP API代码)
java·人工智能·python·api接口·ai去水印·石榴智能·自动去水印
风筝在晴天搁浅10 分钟前
快手 CodeTop LeetCode 227.基本计算器Ⅱ
java·开发语言
2601_9611940214 分钟前
2026初级会计经济法基础知识点汇总
python·django·pdf·virtualenv·代理模式·pygame
0xDevNull16 分钟前
Java实战面试题(一)
java·开发语言
爱就是恒久忍耐22 分钟前
Ubuntu解决pip3安装库提示This environment is externally managed的问题
linux·python·ubuntu