在 Python 中处理中文编码问题时,需重点关注文件编码声明、字符串编码转换及环境配置。以下是分步指南和最佳实践:
一、Python 3 的默认编码行为
- Python 3.x:默认使用 UTF-8 编码(与 Python 2.x 的 ASCII 默认编码不同)
- 验证当前编码:
import sys print(sys.getdefaultencoding()) # 输出: utf-8
二、文件编码声明(关键步骤)
在 Python 文件开头添加编码声明,确保解释器正确解析源码中的中文字符:
# -*- coding: utf-8 -*-
# 或
# coding=utf-8print("中文正常显示") # 无需额外编码转换
三、字符串编码转换
1. 字符串与字节流互转
-
编码(Unicode → 字节流):
text = "你好,世界" bytes_utf8 = text.encode("utf-8") # UTF-8 编码 bytes_gbk = text.encode("gbk") # GBK 编码
-
解码(字节流 → Unicode):
raw_data = b'\xe4\xbd\xa0\xe5\xa5\xbd' # UTF-8 字节流 decoded_str = raw_data.decode("utf-8") # 输出: 你好
2. 错误处理策略
- 跳过非法字符:
errors='ignore'
- 替换非法字符:
errors='replace'
(默认)broken_bytes = b'\xff\xfe你好' safe_str = broken_bytes.decode("utf-8", errors='ignore') # 输出: 你好
四、常见场景解决方案
1. 文件读写
-
指定编码参数(推荐):
# 写入文件 with open("data.txt", "w", encoding="utf-8") as f:f.write("中文内容")# 读取文件 with open("data.txt", "r", encoding="utf-8") as f:content = f.read()
-
处理未知编码:
import chardetwith open("unknown_file.txt", "rb") as f:raw_data = f.read()encoding = chardet.detect(raw_data)["encoding"]text = raw_data.decode(encoding)
2. 控制台输出乱码
-
Windows 命令行(默认 GBK 编码):
# 方法1: 修改代码页为 UTF-8 import os os.system("chcp 65001") # 执行后需重启 Python 环境# 方法2: 重定向标准输出 import sys import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
-
Linux/macOS:通常无需额外配置
3. 数据库/网络通信
- 显式指定编码参数:
# MySQL 连接示例 import pymysql conn = pymysql.connect(host="localhost",user="root",password="123456",database="test",charset="utf8mb4" # 关键参数 )
五、环境配置检查
1. 检查系统默认编码
import locale
print(locale.getpreferredencoding()) # 输出系统默认编码(如 cp936/GBK)
2. 修改环境变量(Windows)
- 临时修改:
set PYTHONIOENCODING=utf-8
- 永久修改:通过注册表调整控制台编码
六、最佳实践
- 统一使用 UTF-8:作为源码文件、数据库、API 通信的标准编码
- 显式指定编码参数:避免依赖系统默认值
- 避免混合编码操作:
# 错误示例:拼接不同编码的字节流 b'GBK字节' + b'UTF8字节'.encode('utf-8') # 抛出 TypeError
- 使用 Pathlib 处理文件路径:
from pathlib import Path Path("中文路径.txt").write_text("内容", encoding="utf-8")
七、常见错误排查
错误信息 | 原因 | 解决方案 |
---|---|---|
UnicodeEncodeError: 'gbk' codec... | 尝试用 GBK 编码 UTF-8 字符 | 指定 encoding=‘utf-8’ |
SyntaxError: Non-UTF-8 code... | 文件编码声明缺失或错误 | 添加 # -*- coding: utf-8 -*- |
UnicodeDecodeError: 'utf-8' codec... | 字节流实际编码与声明不符 | 用 chardet 检测真实编码 |
通过遵循上述实践,可有效解决 90% 以上的中文编码问题。如遇特殊场景(如处理遗留 GBK 文件),建议封装编码转换函数以提高代码可维护性。