本文翻译自我的英文博客,最新修订内容可随时参考:Python中的编码与解码
你真的了解Python中的编码与解码吗?
在计算机中,字符串的存储和网络通信都以字节序列(byte sequence)而非Unicode形式进行。Python的编码(encode)和解码(decode)正是用于在字符串(Unicode)和字节序列之间进行转换的核心机制。
作用:将Unicode字符串转换为指定编码的字节序列,以便存储或传输。
关键要点:
utf-8
、gbk
、ascii
等)。 "你"
在UTF-8中占3字节,在GBK中占2字节)。 s = "你好,世界"
encoded_s = s.encode('utf-8')
print(encoded_s) # 输出: b'\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8c\xe4\xb8\x96\xe7\x95\x8c'
b
表示这是一个字节对象(bytes
类型)。 你
→ 0xE4 0xBD 0xA0
)。 编码 | 特点 | 适用场景 |
---|---|---|
| 可变长编码,支持全球字符,互联网默认编码 | 网页、API数据传输 |
| 双字节编码,仅支持中文字符及部分符号 | 中文Windows系统、老旧系统 |
| 单字节编码,仅支持英文字母、数字和符号 | 纯英文文本、协议头 |
| 定长编码(2字节或4字节),Unicode直接映射 | Windows系统内部文本存储 |
当字符无法被目标编码表示时,会触发UnicodeEncodeError
。
解决方案:通过errors
参数指定处理方式:
# 忽略无法编码的字符(可能导致数据丢失)
s.encode('ascii', errors='ignore')
# 用问号替换(�)
s.encode('ascii', errors='replace')
# 用XML实体替换(如你)
s.encode('ascii', errors='xmlcharrefreplace')
作用:将字节序列转换为Unicode字符串,以便程序处理或显示。
关键要点:
b = b'\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8c\xe4\xb8\x96\xe7\x95\x8c'
decoded_b = b.decode('utf-8')
print(decoded_b) # 输出: 你好,世界
若字节序列包含无效编码(如中途截断的字节),会触发UnicodeDecodeError
。
解决方案:
# 忽略无效字节(可能导致内容缺失)
b.decode('utf-8', errors='ignore')
# 用替换字符(�)表示无效字节
b.decode('utf-8', errors='replace')
# 保留原始字节(如b'\xe4\xbd' → '\ufffd')
b.decode('utf-8', errors='surrogateescape')
类型 | 本质 | 常见操作 |
---|---|---|
| Unicode字符串(逻辑字符序列) | 字符串拼接、正则匹配、格式化 |
| 字节序列(物理存储数据) | 网络传输、文件读写、加密签名 |
# 编码流程:Unicode字符串 → 字节序列(存储/传输)
source_str = "你好"
encoded_bytes = source_str.encode('utf-8') # 编码为UTF-8字节
# 解码流程:字节序列 → Unicode字符串(解析/显示)
received_bytes = encoded_bytes
decoded_str = received_bytes.decode('utf-8') # 解码为原始字符串
场景:用GBK编码的字节序列尝试用UTF-8解码。
s = "测试"
gbk_bytes = s.encode('gbk') # GBK编码:b'\B2\E2\CA\D4'
utf8_str = gbk_bytes.decode('utf-8') # 错误解码 → 输出:æµè¯•
解决方案:确保编码和解码使用相同的字符集。
场景:UTF-16等定长编码需标识字节序(大端/小端)。
# UTF-16LE(小端序)带BOM
s.encode('utf-16') # 输出: b'\xff\xfe\x00\x60\x00\xe4'(\xff\xfe为BOM)
# 忽略BOM解码
b.decode('utf-16-le', errors='ignore')
open('file.txt', 'r', encoding='utf-8')
),避免依赖系统默认编码(可能引发跨平台问题)。 try:
data = bytes_data.decode('utf-8')
except UnicodeDecodeError:
data = bytes_data.decode('utf-8', errors='replace')
response.content.decode('utf-8')
而非str(response.content)
)。 在网络编程中(如HTTP、Socket),数据以字节序列传输,需注意:
Content-Type
字段通常包含编码信息(如text/plain; charset=utf-8
)。 requests
库时,自动根据响应头解码: import requests
response = requests.get('https://example.com')
print(response.text) # 自动用UTF-8解码(若响应头正确)
# 发送方(编码)
message = "你好".encode('utf-8')
socket.send(message)
# 接收方(解码)
data = socket.recv(1024)
message = data.decode('utf-8')
编码与解码是Python处理文本数据的基础,核心逻辑可概括为:
str → bytes
,指定目标编码(如utf-8
)。 bytes → str
,使用与编码一致的编码类型。 通过理解字符编码的底层机制,可有效解决开发中常见的乱码问题,确保数据在存储、传输和显示过程中的一致性。更多细节可参考Python官方文档:字符串与字节序列。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。