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 码的问题!🚀

相关推荐
源码之家2 小时前
计算机毕业设计:Python 共享单车数据分析可视化系统 Flask框架 可视化 大数据 机器学习 深度学习 数据挖掘(建议收藏)✅
大数据·python·数据挖掘·数据分析·汽车·课程设计·美食
爱技术的阿呆2 小时前
R code debug 和 study
开发语言·r语言
SiYuanFeng2 小时前
uv初步介绍及简单的使用方法例子
开发语言·python·uv
寻寻觅觅☆2 小时前
东华OJ-基础题-31-素数(C++)
开发语言·c++·算法
松小白song2 小时前
PID详解+Matlab实现
开发语言·数据结构·matlab
zero15972 小时前
Python 8天极速入门笔记(大模型工程师专用):第八篇-Python 综合实战|完整大模型调用脚本,8 天成果落地
人工智能·python·ai编程·大模型开发
孤魂2332 小时前
机器学习基本概念
python·机器学习
人工干智能2 小时前
科普:<generator object ...>,不是报错!兼谈[x for x in ...]与(x for x in ...)
python